The IHIH Pyramid
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.
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.
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)