33
\$\begingroup\$

I find it fascinating how the letters "H" and "I" are very similar. "H" is a horizontal stroke surrounded by two vertical strokes; "I" is a vertical stroke surrounded by two horizontal strokes (depending on your font). I bet this could be nested... You know what that reminds me of? Fractals!!!

Let's define the "IHIH" pyramid as follows: The first iteration is this ASCII representation of the letter "I":

---
 |
---

The next iteration has a vertical stroke on either side.

|   |
|---|
| | |
|---|
|   |

If you view the "I" in the middle as a single horizontal stroke, then this second iteration is basically an "H". The third iteration adds a horizontal stroke on the top and bottom

-------
 |   |
 |---|
 | | |
 |---|
 |   |
-------

Again, if you view the "H" in the middle as a single vertical stroke, then this iteration is basically an "I". This pattern continues, alternating between "H"s and "I"s on every iteration. For reference, here are the first 6 iterations:

1:
---
 |
---

2:
|   |
|---|
| | |
|---|
|   |

3:
-------
 |   |
 |---|
 | | |
 |---|
 |   |
-------

4:
|       |
|-------|
| |   | |
| |---| |
| | | | |
| |---| |
| |   | |
|-------|
|       |

5:
-----------
 |       |
 |-------|
 | |   | |
 | |---| |
 | | | | |
 | |---| |
 | |   | |
 |-------|
 |       |
-----------

6:
|           |
|-----------|
| |       | |
| |-------| |
| | |   | | |
| | |---| | |
| | | | | | |
| | |---| | |
| | |   | | |
| |-------| |
| |       | |
|-----------|
|           |

The Challenge:

Write a program or function that outputs the N'th iteration of the IHIH pyramid, and an optional trailing newline. Your input will be a single positive integer in whatever reasonable format you want. You do not have to handle invalid inputs, e.g. non-integers, numbers smaller than 1, etc. Your program must at the very least produce the right output for inputs up to 20. Since this is , standard loopholes are not allowed and the shortest answer in bytes wins!

\$\endgroup\$
2
  • \$\begingroup\$ Is it acceptable if I return an arrow of strings one fror each row? \$\endgroup\$ Aug 19, 2016 at 1:13
  • \$\begingroup\$ Didn't quite meeting the challenge criteria, but did something cool by accident... Try it online! \$\endgroup\$ May 21, 2018 at 14:09

24 Answers 24

12
\$\begingroup\$

Python, 165 145 133 123 bytes

A recursive solution:

def i(e):
 d="|";a=e*2;x=d+" "*(a-1)+d
 if e<1:return d
 if e%2:d,x=[" ","-"*(a+1)]
 return[x]+[d+z+d for z in i(e-1)]+[x]

Called with print ("\n".join(i(int(sys.argv[1])))), where the parameter is the iteration number of the IHIH pyramid.

Thanks to @DJMcMayhem for saving 20 bytes. Taking the idea behind those suggestions further saved another 12 bytes. Thanks to @Maltysen for suggestions that trimmed some more bytes.

The function sets the delimiter d to "|" and the intervening spaces to " " (for odd-numbered iterations), deals with returning in the degenerate case, then resets the delimiter to " " and the intervening spaces to "-" for even-numbered iterations. The function returns a list of strings for each line of the IHIH, having embedded the result of a recursive call to the function in the right place within the list.

\$\endgroup\$
3
  • 2
    \$\begingroup\$ Nice answer, and welcome to the site! You do not need to join the lines, a list of strings is fine. A couple tips: change lines 2 and 3 to if e<1:return'|' (no newline between them) then remove the "else" and remove the extra indentation. \$\endgroup\$
    – DJMcMayhem
    Aug 19, 2016 at 2:28
  • 1
    \$\begingroup\$ you can take out the space after return. Also, you can merge the lines without ifs with semicolons, and save on the indentation \$\endgroup\$
    – Maltysen
    Aug 19, 2016 at 3:11
  • 1
    \$\begingroup\$ I've edited your answer. Please feel free to revert my edits if you don't like them. \$\endgroup\$
    – Leaky Nun
    Aug 19, 2016 at 3:43
10
\$\begingroup\$

Cheddar, 186 177 165 154 148 131 bytes

(n,b?,c?,q?,g=s->(n-=1)<0?s:g((q=(c=s.lines[0].len)%4>2?b='|'+" "*c+"|":b='-'*(c+2))+"\n"+s.sub(/^|$/gm,q?'|':' ')+"\n"+b))->g("|")

Uses recursion. Will add explanation once done golfing.

Try it online!

Explanation

This one is a bit complex too keep track off all the variables I'm using but I'll try to keep it simple:

(
 n,    // Input
 b?,   // Stores row to add to top/bottom
 c?,   // Width of string 
 q?,   // false if I-ifying. true if not
 g=
   s->          // Main logic, s is generated string
    (n-=1)<0 ? s :   // Decrease input each iteration. Stop when 0
    g(               // Recurse with....
      (
        q= (         // Set `q` true if h-ifying. false if I-ifying
         c=s.lines[0].len    // Set `c` to width of string
        ) % 4>2 ?
        b='|'+" "*c+"|" :    // Set `b` to top/bottom row adding
        b='-'*(c+2)          // `*` is repeat, c is from before
      ) + "\n" + 
        s.sub(/^|$/gm,       // Add the following to beginning/end of each line
          q?'|':' '          // if H-ifying, add `|`s if I-ifying add spaces
        ) + "\n" + b         // Add bottom row, generated from before
    )
) -> g("|")     // Middle item is `|`

This was a pain to golf but its 55 bytes shorter than original.

\$\endgroup\$
8
\$\begingroup\$

Python 2, 93 bytes

Leaky Nun saved 7 bytes.

r=range(input()+1)
r=r[:0:-1]+r
for y in r:print''.join('| -'[[x%2,y%2+1][x&-2<y]]for x in r)
\$\endgroup\$
3
  • \$\begingroup\$ Closed form :o :o \$\endgroup\$
    – Leaky Nun
    Aug 19, 2016 at 12:52
  • \$\begingroup\$ Ahh, of course: at first I needed int(x/2.) because I was taking range(-n,n+1) but now I can just use those. Thank you! \$\endgroup\$
    – Lynn
    Aug 19, 2016 at 13:03
  • \$\begingroup\$ I specified Python 2 in the header because simply saying "Python" usually means the code works under either Python 2 or Python 3, which is not the case here. \$\endgroup\$
    – user45941
    Aug 19, 2016 at 13:33
7
\$\begingroup\$

Pyth, 50 40 31 25 bytes

j@s.u,J+*\-K+2lheN+jR*2;eN*\-KjR"||"+*dK+J*dKQ]]\|
LXR"|-")CbjyW%Q2uy+K*\-+2lhG+jR*2;GKQ]\|
juCGQuC+K*@"-|"H+3yH+jR*2;GKQ\|
j@CBujR*@"-|"H2CjR*2;GQ\|

Test suite.

Explanation

This is a recursive algorithm.

In each iteration, we perform three actions:

  1. prepend and append a space to each line
  2. transpose the array
  3. prepend and append to each line either "-" or "|" depending on the number of iteration.

After the iterations, the odd-numbered outputs will be transposed. Therefore, we transpose them.

j@CBujR*@"-|"H2CjR*2;GQ\|   input: Q
j@CBujR*@"-|"H2CjR*2;GQ\|Q  implicit filling of arguments


    u                 Q\|   for Q times, starting with "|", G as current output,
                            H as number of iterations:

                jR*2;G          prepend and append a space to each line
                                (using each line as separator, join [" "," "])
               C                transpose
     jR*      2                 prepend and append the following to each line:
        @"-|"H                      the H-th element of the string "-|" (modular indexing)

 @CB                     Q  select the Q-th element from [output,
                            transposed output] (modular indexing)
j                           join by newlines
\$\endgroup\$
1
  • \$\begingroup\$ I love the transponation idea. \$\endgroup\$
    – Titus
    Aug 26, 2016 at 3:46
7
\$\begingroup\$

Matricks, 80 62 bytes

An iterative solution (Recursion in Matricks is hard...)

Run with python matricks.py ihih.txt [[]] <input> --asciiprint

k124;FiQ%2:v;b[m124:Q*2+3:1;];a{z:Q*2+1;};:b;v[m45:1:Q*2+3;];u{zQ*2+1:;};;:1:n;;
k124;FiQ%2:v;b[m124:Q*2+3:2;];B1;:b;v[m45:2:Q*2+3;];V1;;:1:n;;

Explanation:

k124;                 # Set the matrix to '|'
F...:1:n;;            # Repeat input times, (Q is iteration variable)
  iQ%2:...:...;       # if statement, check if Q is odd or even
                      # Q is even,
    b;                # Make space to the left
    v[m45:2:Q*2+3;];  # Set the top 2 rows to '-'s
    V1;               # Rotate the matrix up 1 unit, moving the topmost row to the bottom
                      # Q is odd,
    v;                # Make space above
    b[m124:Q*2+3:2;]; # Set the 2 left columns to '|'s
    B1;               # Rotate the matrix left 1 unit, moving the leftmost row to the right
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Wow, iterative! I'm impressed. \$\endgroup\$ Aug 19, 2016 at 3:41
  • \$\begingroup\$ @ConorO'Brien Matricks was built for dynamic matrix resizing, so it's not THAT impressive, but thanks anyway! \$\endgroup\$
    – Blue
    Aug 19, 2016 at 3:42
5
\$\begingroup\$

JavaScript (ES6), 92 90 bytes

f=
(n,[h,c,v]=n&1?`-- `:` ||`)=>n?(c+=h.repeat(n+n-1)+c)+`
${f(n-1).replace(/^|$/gm,v)}
`+c:v
;
<input type=number min=0 oninput=o.textContent=f(+this.value)><pre id=o>

Recursive solution works by taking the previous iteration, adding the v character to the sides, then adding the c character to the corners and the h character along the top and bottom. The set of characters simply alternates each iteration. Edit: Saved 2 bytes by returning v when n=0.

\$\endgroup\$
4
\$\begingroup\$

Dyalog APL, 52 43 bytes

{v=⊃⍵:h⍪⍨h⍪s,⍵,s⋄v,⍨v,s⍪⍵⍪s}⍣⎕⍪⊃v h s←'|- '

v h s←'|- ' assigns the three characters to three names (vertical, horizontal, space)

the first one, i.e. |

make into 1×1 table

{...}⍣⎕ get input and apply the braced function that many times

v=⊃⍵: if the top-left character of the argument is a vertical, then:

  h⍪⍨ horizontals below

  h⍪ horizontals above

  s, spaces to the left of

  ⍵,s the argument with spaces to the right

else:

  v,⍨ verticals to the right of

  v, verticals to the left of

  s⍪ spaces above

  ⍵⍪s the argument with spaces below

TryAPL online!

\$\endgroup\$
3
\$\begingroup\$

Brachylog, 84 bytes

,[[["|"]]:?:1]i:1:zi:ca~@nw
hh~m["-|":B]:ramggL," "ggS,?:Sz:ca:Srz:caz:Lz:ca:Lrz:ca.

Try it online!

A port of my answer in Pyth.

\$\endgroup\$
3
\$\begingroup\$

C, 110 bytes

#define R(A,B,C)for(A=n,B=1;A<=n;putchar(C),A-=B|=-!A)
f(n,y,x,w,v){R(y,w,10)R(x,v,"| -"[x/2*2<y?y%2+1:x%2]);}

Invoke as f(n). For 111 bytes, I could do:

f(n,y,x,w,v){for(y=n,w=1;y<=n;y-=w|=-!y,puts(""))for(x=n,v=1;x<=n;x-=v|=-!x)putchar("| -"[x/2*2<y?y%2+1:x%2]);}

i.e., the #define saves exactly one byte.

\$\endgroup\$
3
\$\begingroup\$

Dyalog APL, 34 bytes

{⍉⍣⍵{b,b,⍨⍉s,⍵,⊃s b←' -|'~⊃⍵}⍣⍵⍪'|'}

{...}⍣⍵⍪'|' Apply function in braces times starting with 1x1 matrix of character |. The result of each application is the argument for the next application.

s b←' -|'~⊃⍵ s is space and b is the bar not in the top left corner of the argument (' -|'~'-' removes horizontal bar and leaves space and vertical bar)

s,⍵,⊃s b add space to left and right ( picks s from vector s b)

b,b,⍨⍉ transpose and add b to left and right

For odd numbers this leaves the result transposed, so a final transpose is required.

⍉⍣⍵ Transpose times (once would be enough, but shorter to code this way)

TryAPL online

\$\endgroup\$
2
  • \$\begingroup\$ Welcome to PPCG! \$\endgroup\$
    – Stephen
    Aug 18, 2017 at 21:24
  • \$\begingroup\$ Thanks! Trying to join the party now, lots of fun solving these :) \$\endgroup\$
    – Gil
    Aug 18, 2017 at 21:31
3
\$\begingroup\$

APL (Dyalog Classic), 34 bytes

'- |'[2+∘.(≤-(1+=)×2|⌈)⍨(⌽,0,⊢)⍳⎕]

Try it online!

(uses ⎕io←1)

⍳⎕ is 1 2 ... N

(⌽,0,⊢) is a train that turns it into -N ... -1 0 1 ... N

∘.( )⍨ executes the parentheses for every pair of coordinates ⍺ ⍵

the train (≤-(1+=)×2|⌈) or its dfn equivalent {(⍺≤⍵)-(1+⍺=⍵)×2|⍺⌈⍵} produces a matrix like:

 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1
  0  1  0  0  0  0  0  0  0  1  0
  0  1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1  1  0
  0  1  0  1  0  0  0  1  0  1  0
  0  1  0  1 ¯1 ¯1 ¯1  1  0  1  0
  0  1  0  1  0  1  0  1  0  1  0
  0  1  0  1 ¯1 ¯1 ¯1  1  0  1  0
  0  1  0  1  0  0  0  1  0  1  0
  0  1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1  1  0
  0  1  0  0  0  0  0  0  0  1  0
 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1

'- |'[2+ ] makes these valid indices in ⎕IO=1 and picks the corresponding characters

\$\endgroup\$
1
  • \$\begingroup\$ A rare occurrence where a full program and dfn have the same bytecount. \$\endgroup\$
    – Razetime
    Oct 31, 2020 at 15:04
2
\$\begingroup\$

Cheddar, 107 bytes

(n,g=n->n?(f->f(f(g(n-1)," ").turn(1),n%2?"-":"|"))((a,b)->a.map(i->b+i+b)):["|"])->(n%2?g(n).turn(1):g(n))

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Cheddar, 85 bytes

(n,r=(-n|>n).map(v->abs v))->r.map(y->r.map(x->"| -"[(x&-2)<y?y%2+1:x%2]).fuse).vfuse

My first Cheddar answer. Try it online!

If I try to write r=(-n|>n).map(v->abs v).map, and then r(y->r(x->…)), the interpreter crashes. ;-;

\$\endgroup\$
3
  • \$\begingroup\$ You can make v->abs v into (abs) (e.g. r.map((abs))) which will return a function which has the behavior of the abs function. e.g. (+)(1,2) -> 3. (^)(2,6) -> 64. Also big wow on outgolfing me by almost 50% \$\endgroup\$
    – Downgoat
    Aug 20, 2016 at 19:09
  • \$\begingroup\$ No, I tried that: Runtime Error: `abs` has no behavior for types `Number` and `Number` (because map receives both the element and its index, presumably.) \$\endgroup\$
    – Lynn
    Aug 20, 2016 at 20:34
  • \$\begingroup\$ ah :/ i was just about to fix that bug today >_> \$\endgroup\$
    – Downgoat
    Aug 21, 2016 at 1:12
1
\$\begingroup\$

Ruby, 81 78 77 bytes

This is based on Lynn's Python answer. Golfing suggestions welcome.

Edit: 3 bytes thanks to Lynn. Corrections and golfing 1 byte thanks to Jordan.

->n{r=(-n..n).map &:abs;r.map{|y|puts r.map{|x|"| -"[x&-2<y ?y%2+1:x%2]}*""}}

Ungolfing:

def f(n)
  r = -n..n            # Range from -n to n (inclusive)
  r = r.map{|i|i.abs}  # Turns every element of r positive
  r.each do |y|
    s = ""             # a line of the fractal
    r.each do |x|      # build up the fractal based on x and y
      if x/2*2 < y
        s += " -"[y%2]
      else
        s += "| "[x%2]
      end
    end
    puts s             # print the line
  end
end
\$\endgroup\$
5
  • \$\begingroup\$ Can you .map(&:abs)? \$\endgroup\$
    – Lynn
    Aug 19, 2016 at 13:31
  • \$\begingroup\$ @Lynn Well spotted. Any other suggestions? \$\endgroup\$
    – Sherlock9
    Aug 19, 2016 at 13:37
  • \$\begingroup\$ The first * isn't doing anything. You can use *"" instead of .join. Also, using p surrounds each line with quotation marks (it calls inspect on its arguments), which might disqualify you. \$\endgroup\$
    – Jordan
    Aug 20, 2016 at 0:26
  • \$\begingroup\$ Also, you can remove the parentheses around &:abs (map &:abs). You might be able to do something with Array#product instead of nested maps, but it'll make line breaks tricky. \$\endgroup\$
    – Jordan
    Aug 20, 2016 at 0:42
  • \$\begingroup\$ @Jordan Your first four hints work, but r.product(r).map (however that works) is longer and does not appear to allow line breaks very easily. \$\endgroup\$
    – Sherlock9
    Aug 20, 2016 at 7:42
1
\$\begingroup\$

MATLAB, 168 163 bytes

This is probably not the cleverest way to do it: Expanding a string on all sides in n steps:

function s=g(n);s='|';for m=1:n;if mod(m,2);a=45;b=a;c=0;else a='|';b=0;c=a;end;s=[a repmat(b,1,2*m-1);repmat(c,2*m-1,1) s];s(:,end+1)=s(:,1);s(end+1,:)=s(1,:);end

Usage: Save as g.m (do I have to add that to the byte count?) and call e.g. g(15).

Ungolfed:

function s=g(n)

% // Initialize s
s = '|';

for m=1:n
   % // Decide if odd or even number and which symbol to add where
   if mod(m,2)
      a=45;b=a;c=0; % // char(45) is '-' and char(0) is ' ' (thx to Luis Mendo)
   else
      a='|';b=0;c=a;
   end
      % // Add symbols at top and left to s
      s = [a repmat(b,1,2*m-1);repmat(c,2*m-1,1) s];
      % // Add symbols at right and bottom to s
      s(:,end+1) = s(:,1);
      s(end+1,:) = s(1,:);
end
\$\endgroup\$
1
  • \$\begingroup\$ You can replace ' ' by 0 (Matlab treats char 0 as a space) and '-' by 45. File name doesn't have to be included in byte count \$\endgroup\$
    – Luis Mendo
    Aug 19, 2016 at 9:41
1
\$\begingroup\$

Actually, 48 45 44 bytes

This is an attempt to port my Ruby answer to Actually. This is way too long and golfing suggestions are very much appreciated. Try it online!

u;±ux♂A╗╜`╝╜";2@%2╛%u╛(2±&<I'-' '|++E"£MΣ.`M

Here is a 46-byte version which separates out the nested functions so that we can define "| -" in fewer bytes. Try it online!

u;±ux♂A╗╜`;2@%2╛%u╛(2±&<I"| -"E`#"╝╜%r£MΣ."%£M

Ungolfing:

First algorithm

u         Increment implicit input.
;±u       Duplicate, negate, increment. Stack: [-n n+1]
x♂A       Range [-n, n+1). Abs(x) over the range.
╗         Save list to register 0. Let's call it res.
╜         Push res so we can iterate over it.
  `         Start function (with y from map() at the end)
  ╝         Save y to register 1.
  ╜         Push res so we can iterate over it.
    "         Start function as string (with x from map() at the end)
    ;         Duplicate x.
    2@%       x mod 2.
    2╛%u      y mod 2 + 1.
    ╛(2±&<I   If x&-2 < y, then y%2+1, else x%2.
    '-' '|++  Push "| -" (We're inside a string right now,
                          so we need to push each char individually)
    E         Grab index of "| -"
    "£        End string and turn into function.
  M         Map over res.
  Σ.        sum() (into a string) and print.
  `         End function.
M         Map over res.

Second algorithm

u;±ux♂A╗╜                  Create res as before.
`;2@%2╛%u╛(2±&<I"| -"E`#   The inner function from the first algorithm put into a list.
                             The only change to the function is the definition of "| -".
"╝╜  £MΣ."                 Most of the outer function from the first algorithm as a string.
   %r      %               %-formats the list into the outer function.
            £M             Turns the string into a function, maps over res.
\$\endgroup\$
1
  • \$\begingroup\$ u;±ux♂A╗╜`;2@%2╛%u╛(2±&<I"| -"E`#"╝╜%r£Mεj."%£M is longer than what you currently have (by 2 bytes), but you might find some inspiration for ways to make it shorter that I'm not seeing. \$\endgroup\$
    – user45941
    Aug 21, 2016 at 7:48
1
\$\begingroup\$

Canvas, 19 18 17 14 bytes

|╶[ e↷l|*e}╶[↷

Try it here!

If I were allowed to output every other output rotated 90°, the last 4 characters could be removed.

Explanation (some characters have been changed to look ~monospace):

|               push "|" - the canvas
 ╶[       }     repeat input times
    e             encase the canvas in spaces horizontally
     ↷            rotate the canvas 90°
      l|*         push "-" repeated the canvas height times vertically
         e        and encase the canvas if two of those horizontally
           ╶[   repeat input times
             ↷    rotate the canvas 90°
\$\endgroup\$
3
  • \$\begingroup\$ I'd lose 6 bytes if they loosened that restriction too :P. \$\endgroup\$ May 21, 2018 at 15:45
  • \$\begingroup\$ @MagicOctopusUrn wellp, make that -5 bytes for me :p (could your answer benefit from a transpose loop as well?) \$\endgroup\$
    – dzaima
    May 21, 2018 at 16:15
  • \$\begingroup\$ my implementation is a transpose loop :D. \$\endgroup\$ May 21, 2018 at 16:48
1
\$\begingroup\$

05AB1E, 29 28 bytes

„|-S¹>∍ƶćsvy‚˜.Bζ}¹Fζ}»R.∞.∊

Try it online!

-1 thanks to Dzaima...

This is an iterative solution.


Essentially This is made by creating the following pattern:

['|','--','|||',...]

Then, pairwise, transposing each element together and adding the padding.

By transposing after each iteration, we end up creating a single corner of the pattern.

Then, we can use 05AB1E's reflection commands.


„|-S                         # Push ['|','-']
    ¹>∍                      # Extended to input length.
       ƶ                     # Each element multiplied by its index.
        ćs                   # Extract head of list, swap remainder to top.
          v      }           # For each element in the '|-' list...
           y‚˜               # Wrap current 2D array with new entry, flatten.
              .Bζ            # Pad and transpose, leaving it transposed for the next addition.
                 }           # End loop.
                  ¹Fζ}       # Transpose N times.
                      »R     # Bring it all together into a newline string, reverse.
                        .∞.∊ # Mirror horizontally, then vertically with overlap.
\$\endgroup\$
0
1
\$\begingroup\$

Stax, 22 bytes

âeò↕\┐▄┤╚╬8φ8Δ☺Pä≤δ₧߃

Run and debug it

Unpacked, ungolfed, and commented, it looks like this.

'|          string literal "|"
{           begin block to repeat
  . |G      push " |", then jump to trailing `}` below 
  '-z2lG    push ["-",[]], then jump to trailing `}` below again
}N          repeat block according to number specified in input
m           output each row in grid

}           goto target - `G` from above jumps to here
  i@        modularly index into pair using iteration index
  ~         push to input stack
  {;|Sm     surround each row with the extracted element
  M         transpose grid

Run this one

\$\endgroup\$
0
\$\begingroup\$

Mathematica, 158 164 bytes

f[n_]:=Print/@StringJoin/@Map[{{{"|","|", },{ , , }},{{"|", ,"-"},{ ,"-","-"}}}[[##]]&@@#&,Table[{1+i~Mod~2, 1+j~Mod~2, 2+Sign[Abs[i]-Abs[j]]}, {i,-n,n}, {j,-n,n}],{2}]

Mathematically calculates the correct symbol at the coordinates (i,j), where both run from -n to n. Human formatted:

f[n_]:=Print/@
 StringJoin/@
  Map[
   {{{"|","|", },{ , , }},{{"|", ,"-"},{ ,"-","-"}}[[##]]&@@#&,
   Table[{1+i~Mod~2,1+j~Mod~2,2+Sign[Abs[i]-Abs[j]]},{i,-n,n},{j,-n,n}],
   {2}]
\$\endgroup\$
0
0
\$\begingroup\$

PHP, 166 bytes

golfed more than 100 bytes off my first approach and it´s still the longest answer here.

function i($n){for($m=['|'];$k++<$n;){array_unshift($m,$m[]=str_repeat(' -'[$f=$k&1],2*$k-1));foreach($m as$i=>&$r)$r=($c='||- '[2*$f+($i&&$i<2*$k)]).$r.$c;}return$m;}

breakdown

function h($n)
{
    for($m=['|'];$k++<$n;)
    {
        array_unshift($m,$m[]=str_repeat(' -'[$f=$k&1],2*$k-1));
        foreach($m as$i=>&$r)
            $r=($c='||- '[2*$f+($i&&$i<2*$k)]).$r.$c;
    }
    return$m;
}

ungolfed

function ihih($n)
{
    $m=['|'];                   // iteration 0
    for($k=1;$k<=$n;$k++)       // loop $k from 1 to $n
    {
        $f=$k&1;                        // flag for odd iterations
        // add lines:
        $r=str_repeat(' -'[$f],2*$k-1); // new line: ' ' for even, '-' for odd iterations
        $m[]=$r;                                // append
        array_unshift($m,$r);                   // prepend
        // add columns:
        foreach($m as$i=>&$r)           // for each line
        {
            $c='| '[$f];                        // '|' for even, ' ' for odd iterations
            if($f && (!$i || $i==2*$k)) $c='-'; // '-' in corners for odd iterations
            $r=$c.$r.$c;                        // prepend and append character
        }
    }
    return $m;
}
\$\endgroup\$
0
\$\begingroup\$

Perl 5, 150 bytes

sub h{my$i=pop;my$c=$i%2?$":'|';return(map{"$c$_$c"}h($i-1)),$i%2?'-'x($i*2+1):$c.$"x($i*2-1).$c if$i;()}say for reverse(@q=h<>),$q[0]=~s/---/ | /r,@q

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Haskell, 110 bytes

f 0=["|"]
f n|odd n=g ' '!n$'-'|1>0=g '|'$id!n$' '
g c=map$(c:).(++[c])
(g!n)c|p<-g.f$n-1=(:p)<>pure$c<$head p

Try it online!

Explanation/Ungolfed

The helper function g takes a character and a list of strings, it then pre- and appends that character to each string:

g c = map (\s-> [c] ++ s ++ [c])

Next the operator (!) takes a function (g), a number (n) and a character (c). It then computes the output for n-1, applies the function g to it and adds a string of the same width consisting of cs to the beginning and end:

(g ! n) c | prev <- g $ f (n-1), ln <- [c | _ <- head p]
          = [ln] ++ prev ++ [ln]

With these we'r ready to generate the outputs recursively, first we need to cover the base case:

f 0 = ["|"]

And then the recursion:

-- for odd n: the previous output needs a space at the end and beginning and then a string of '-' characters at the top and bottom
f n | odd n     = (g ' ' ! n) '-'
-- for even n: the previous output needs a line of spaces at the top and bottom and then each line needs to be enclosed with '|' characters
    | otherwise = g '|' $ (id ! n ) ' '
\$\endgroup\$
0
\$\begingroup\$

J, 37 bytes

f=:{&' |-'@*@(-:@=+<-2&|@>.)"{~@:|@i:

TIO

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.