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 code-golf, standard loopholes are not allowed and the shortest answer in bytes wins!
-
\$\begingroup\$ Is it acceptable if I return an arrow of strings one fror each row? \$\endgroup\$Rohan Jhunjhunwala– Rohan Jhunjhunwala2016年08月19日 01:13:11 +00:00Commented Aug 19, 2016 at 1:13
-
\$\begingroup\$ Didn't quite meeting the challenge criteria, but did something cool by accident... Try it online! \$\endgroup\$Magic Octopus Urn– Magic Octopus Urn2018年05月21日 14:09:40 +00:00Commented May 21, 2018 at 14:09
24 Answers 24
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.
-
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– DJMcMayhem2016年08月19日 02:28:26 +00:00Commented Aug 19, 2016 at 2:28 -
1\$\begingroup\$ you can take out the space after
return. Also, you can merge the lines withoutifs with semicolons, and save on the indentation \$\endgroup\$Maltysen– Maltysen2016年08月19日 03:11:55 +00:00Commented 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– Leaky Nun2016年08月19日 03:43:47 +00:00Commented Aug 19, 2016 at 3:43
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.
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.
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)
-
\$\begingroup\$ Closed form :o :o \$\endgroup\$Leaky Nun– Leaky Nun2016年08月19日 12:52:16 +00:00Commented Aug 19, 2016 at 12:52
-
\$\begingroup\$ Ahh, of course: at first I needed
int(x/2.)because I was takingrange(-n,n+1)but now I can just use those. Thank you! \$\endgroup\$lynn– lynn2016年08月19日 13:03:10 +00:00Commented 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– user459412016年08月19日 13:33:14 +00:00Commented Aug 19, 2016 at 13:33
Pyth, (削除) 50 (削除ここまで) (削除) 40 (削除ここまで) (削除) 31 (削除ここまで) 25 bytes
(削除) [email protected],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\|
Explanation
This is a recursive algorithm.
In each iteration, we perform three actions:
- prepend and append a space to each line
- transpose the array
- 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
-
\$\begingroup\$ I love the transponation idea. \$\endgroup\$Titus– Titus2016年08月26日 03:46:06 +00:00Commented Aug 26, 2016 at 3:46
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
-
1\$\begingroup\$ Wow, iterative! I'm impressed. \$\endgroup\$Conor O'Brien– Conor O'Brien2016年08月19日 03:41:01 +00:00Commented 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– Blue2016年08月19日 03:42:15 +00:00Commented Aug 19, 2016 at 3:42
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.
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 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
Brachylog, 84 bytes
,[[["|"]]:?:1]i:1:zi:ca~@nw
hh~m["-|":B]:ramggL," "ggS,?:Sz:ca:Srz:caz:Lz:ca:Lrz:ca.
A port of my answer in Pyth.
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.
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)
APL (Dyalog Classic), 34 bytes
'- |'[2+∘.(≤-(1+=)×ばつ2|⌈)⍨(⌽,0,⊢)⍳⎕]
(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
-
\$\begingroup\$ A rare occurrence where a full program and dfn have the same bytecount. \$\endgroup\$Razetime– Razetime2020年10月31日 15:04:24 +00:00Commented Oct 31, 2020 at 15:04
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. ;-;
-
\$\begingroup\$ You can make
v->abs vinto(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– Downgoat2016年08月20日 19:09:55 +00:00Commented Aug 20, 2016 at 19:09 -
\$\begingroup\$ No, I tried that:
Runtime Error: `abs` has no behavior for types `Number` and `Number`(becausemapreceives both the element and its index, presumably.) \$\endgroup\$lynn– lynn2016年08月20日 20:34:35 +00:00Commented Aug 20, 2016 at 20:34 -
\$\begingroup\$ ah :/ i was just about to fix that bug today >_> \$\endgroup\$Downgoat– Downgoat2016年08月21日 01:12:13 +00:00Commented Aug 21, 2016 at 1:12
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
-
\$\begingroup\$ Can you
.map(&:abs)? \$\endgroup\$lynn– lynn2016年08月19日 13:31:44 +00:00Commented Aug 19, 2016 at 13:31 -
\$\begingroup\$ @Lynn Well spotted. Any other suggestions? \$\endgroup\$Sherlock9– Sherlock92016年08月19日 13:37:49 +00:00Commented Aug 19, 2016 at 13:37
-
\$\begingroup\$ The first
*isn't doing anything. You can use*""instead of.join. Also, usingpsurrounds each line with quotation marks (it callsinspecton its arguments), which might disqualify you. \$\endgroup\$Jordan– Jordan2016年08月20日 00:26:44 +00:00Commented Aug 20, 2016 at 0:26 -
\$\begingroup\$ Also, you can remove the parentheses around
&:abs(map &:abs). You might be able to do something withArray#productinstead of nestedmaps, but it'll make line breaks tricky. \$\endgroup\$Jordan– Jordan2016年08月20日 00:42:04 +00:00Commented 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– Sherlock92016年08月20日 07:42:03 +00:00Commented Aug 20, 2016 at 7:42
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
-
\$\begingroup\$ You can replace
' 'by0(Matlab treats char 0 as a space) and'-'by45. File name doesn't have to be included in byte count \$\endgroup\$Luis Mendo– Luis Mendo2016年08月19日 09:41:09 +00:00Commented Aug 19, 2016 at 9:41
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.
-
\$\begingroup\$
u;±ux♂A╗╜`;2@%2╛%u╛(2±&<I"| -"E`#"╝╜%r£Mεj."%£Mis 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– user459412016年08月21日 07:48:37 +00:00Commented Aug 21, 2016 at 7:48
Canvas, (削除) 19 (削除ここまで) (削除) 18 (削除ここまで) (削除) 17 (削除ここまで) 14 bytes
|╶[ e↷l|*e}╶[↷
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°
-
\$\begingroup\$ I'd lose 6 bytes if they loosened that restriction too :P. \$\endgroup\$Magic Octopus Urn– Magic Octopus Urn2018年05月21日 15:45:55 +00:00Commented 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– dzaima2018年05月21日 16:15:08 +00:00Commented May 21, 2018 at 16:15
-
\$\begingroup\$ my implementation is a transpose loop :D. \$\endgroup\$Magic Octopus Urn– Magic Octopus Urn2018年05月21日 16:48:40 +00:00Commented May 21, 2018 at 16:48
05AB1E, (削除) 29 (削除ここまで) 28 bytes
„|-S1>∍ƶćsvy‚ ̃.Bζ}1Fζ}»R.∞.∊
-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 ['|','-']
1>∍ # 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.
1Fζ} # Transpose N times.
»R # Bring it all together into a newline string, reverse.
.∞.∊ # Mirror horizontally, then vertically with overlap.
Stax, 22 bytes
âeò↕\┐▄┤╚╬8φ8Δ☺Pä≤δ₧߃
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
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}]
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;
}
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
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 ) ' '