# Happy Fibonacci Day!

## Background

Today (or Yesterday)'s is (or was) 11/23 or Fibonacci day! What better way to celebrate than to make a fibonacci cake?

## Examples

3

ii
i_i_ii_i_i

8

ii
ii
ii
ii
ii
ii
ii
ii
i ii i
i ii i
i ii i
i ii i
i ii i
i i ii i i
i i ii i i
i i ii i i
i i i ii i i i
i i i ii i i i
i i i i ii i i i i
i i i i i ii i i i i i
i_i_i_i_i_i_i_ii_i_i_i_i_i_i_i

## Challenge

You're not really making a cake, just the candles because I can't ascii-art a cake

To make the cake you must first get the first n fibonacci numbers sorted ascending. The candle (i)'s height is determined by value of the current fibonacci number. The candles are separated by an underscore (_).

The cake should be symmetrical. So the candles should then be flipped and concatenated.

## Example Construction

Input: 6
First 6 Fibonacci Numbers: 1, 1, 2, 3, 5, 8
Candle heights:

i
i
i
i i
i i
i i i
i i i i
i i i i i i
-----------
1 1 2 3 5 8

Output would be:
ii
ii
ii
i ii i
i ii i
i i ii i i
i i i ii i i i
i_i_i_i_i_ii_i_i_i_i_i

## Reference Fibonacci Numbers

For reference, here are the first 15 fibonacci numbers. In this challenge, you'll be starting at 1.

1,1,2,3,5,8,13,21,34,55,89,144,233,377,610
• I regret to inform the West Coast of the United States that for most of the world, 11/23 is over or almost over :( This has just turned from code-golf to fastest-code – cat Nov 24 '15 at 3:01
• @sysreq That's okay, they just need to travel to the west coast (instantly), and then they can enjoy Fibonacci day for a last 5 hours (7 for hawaii) :p – Downgoat Nov 24 '15 at 3:05
• This challenge is going to be legendary in 43 years (11/23/58). – Arcturus Nov 24 '15 at 4:43
• In 43 years the mm/dd/yy date format will be history. All intelligent beings will have switched to yyyy/mm/dd... :-P – user19214 Nov 24 '15 at 5:18
• @sysreq Posting golfed answers in verbose languages is very much encouraged. Of course, you're not competing with Pyth, but you can compete with other answers in the same language or in languages of comparable verbosity. – Martin Ender Nov 24 '15 at 9:33

# Pyth, 31 bytes

jaPJ_.ts_BuaaGks>4GtQ]\idXeJ" _

Try it online: Demonstration

### Explanation:

jaPJ_.ts_BuaaGks>4GtQ]\idXeJ" _   implicit: Q = input number
aGk                      append the empty string to G
a   s>4G                  append the sum of the last 4 strings in G to G
this gives ["i", "", "i", "", "ii", "", "iii",..]
s_B                        extend the list with the reversed list
.t                  d        pad to a rectangle with spaces and transposes
J_                             reverse the order and assign to J
PJ                              remove the last string of J
a                                and append
XeJ" _   the last string of J with spaces replaced by "_"
j                                 print each string on a separate line

# J, 58 bytes

3 :''' i_''{~|.|:(,|.)(#&1,2#~0&=)"*}.,0,.(%-.-*:)t.1+i.y'

Uses (%-.-*:)t. for Fibonacci generation. Explanation might come a bit later.

Usage:

f=.3 :''' i_''{~|.|:(,|.)(#&1,2#~0&=)"*}.,0,.(%-.-*:)t.1+i.y'
f 5
ii
ii
i ii i
i i ii i i
i_i_i_i_ii_i_i_i_i

Try it online here.

# CJam, 41 39 bytes

"i""_"1$ri({1$1$4$+}*]),f{Se[}W<_W%+zN*

This prints a fair amount of leading whitespace. Try it online in the CJam interpreter.

### How it works

"i""_"1$e# Push "i", "_", and a copy of "i". ri( e# Read an integer from STDIN and subtract 1. { e# Do that many times: 1$     e#   Copy the last underscore.
1$4$+  e#   Copy the last strings of i's and concatenate them.
}*       e#
]),      e# Wrap the results in an array, pop the last string, and get its length.
f{       e# For each remaining string, push the string and the length; then:
Se[    e#   Pad the string to that length by prepending spaces.
}
W<       e# Remove the last string (underscore).
e# We have now generated the columns of the left half of the output.
_W%+     e# Append a reversed copy (columns of right half).
z        e# Transpose rows with columns.
N*       e# Separate the rows by linefeeds.

# TeaScript, 9384 76 + 1 = 77 bytes

+1 byte for "Inputs are numbers?" checkbox

Ungolfed version:

r(x)m(#(p.R((w=F(x))-F(i+1))+"i"R(F(i+1))))t()m(#(j=i<w-1?" ":"_",(A=ls.m(#i>0?j+l:l)j)+Av))j

Thanks to @Vɪʜᴀɴ for the tips.

• You should be able to use the r function instead of A(x)f(0), e.g. r(x)m(# – Downgoat Nov 24 '15 at 3:46
• @Vɪʜᴀɴ Thanks. What does Array.dupe() do, it doesn't seem to work? – intrepidcoder Nov 24 '15 at 3:49
• Array.dupe was probably a bad name, it removes duplicates from an array. – Downgoat Nov 24 '15 at 3:49
• @Vɪʜᴀɴ You should put a summary of each method in the property names section with the input/output args. Also, Array.repeat and String.reverse would be nice too. – intrepidcoder Nov 24 '15 at 3:56
• @sysreq I meant ungolfed, sorry for the confusion. – intrepidcoder Nov 24 '15 at 14:07

## Python 2, 117 bytes

a=b='i'
l=a,
exec"l+='_',b,;a,b=b,b+a;"*~-input()
for r in map(None,*l+l[::-1])[::-1]:print''.join(x or' 'for x in r)

The idea is simple: generate the picture in columns going bottom to top, left to right, with the mirrored right half the reverse of the left. The columns are generated by iterating the Fibonacci recurrence, on strings of i's, interspersed with _'s for the bottom row.

To print the picture with columns starting from the bottom, we need to rotate it, which means transposing and reversing. Unfortunately, Python doesn't have a simple way to transpose an array of unequal-length rows. The built-in zip truncates to the shortest row. This uses the map(None,_) trick, but has to convert all the None to spaces afterwards.

import Data.List
f=0:scanl(+)1f
b n c s|length s<n=b n c(c:s)|0<1=s
m s=s++reverse s
c n=mapM_ putStrLn$transpose$m$map(b(f!!n)' ')$intersperse"_"\$map(\x->[1..f!!x]>>"i")[1..n]

Call c.

(f shamelessly stolen from https://stackoverflow.com/questions/232861/fibonacci-code-golf)

• You can replace flip replicate 'i'.(f!!) by \x->[1..f!!x]>>"i". – nimi Nov 27 '15 at 14:39
• Great, thanks! This is the first time I actually understand a monadic golfing tip, even though I don't come up with those myself yet. No clue as to how f works still... – Leif Willerts Nov 28 '15 at 1:49

# Matlab, 172 152 bytes

Unfortunately, Matlab hasn't a build in Fibonacci function and string Manipulation is a bit fiddly.

function t(n);f=@(n)getfield([0 1;1 1]^n,{3});m=char(flipud(bsxfun(@(a,b)(a<=f(b/2)&mod(b,2)==0)*'i',(1:f(n))',2:2*n)));m(end,2:2:end)='_';[m fliplr(m)]

With line breaks:

function t(n);
f=@(n)getfield([0 1;1 1]^n,{3});
m=char(flipud(bsxfun(@(a,b)(a<=f(b/2)&mod(b,2)==0)*'i',(1:f(n))',2:2*n)));
m(end,2:2:end)='_';
[m fliplr(m)]

# Ruby, 151146142137 132 bytes

->n{s=1,1;3.upto(n){s<<s[-1]+s[-2]};s.map!{|i|[' ']*(s[-1]-i)+[?i]*i}.transpose.map!{|a|v=a*'_ '[a.count(?i)<=>n];puts v+v.reverse}}

137 bytes

->n{s=1,1;3.upto(n){s<<s[-1]+s[-2]};o=s.map{|i|[' ']*(s[-1]-i)+[?i]*i}.transpose.map{|a|v=a*' ';v+v.reverse};o[-1]=o[-1].tr' ',?_;puts o}

142 bytes

->n{s=1,1;(3..n).map{s<<s[-1]+s[-2]};puts s.map{|i|[' ']*(s[-1]-i)+[?i]*i}.transpose.map{|a|v=a*' ';v+v.reverse}.tap{|c|c[-1]=c[-1].tr' ',?_}}

146 bytes

->n{s=1,1;(3..n).map{s<<s[-1]+s[-2]};puts s.map{|i|[' ']*(s[-1]-i)+[?i]*i}.transpose.map{|a|v=a.join' ';v+v.reverse}.tap{|c|c[-1]=c[-1].tr' ',?_}}

151 bytes

->n{s=1,1;(3..n).map{s<<s[-1]+s[-2]};puts s.map{|i|[' ']*(s[-1]-i)+['i']*i}.transpose.map{|a|v=a.join ' ';v+v.reverse}.tap{|c|c[-1]=c[-1].tr ' ', '_'}}

Ungolfed:

-> n {
s = 1,1
3.upto(n) {
s << s[-1] + s[-2]
}
s.map! { |i|
[' '] * (s[-1]-i) + [?i] * i
}.
transpose.
map! { |a|
v = a * '_ '[a.count(?i)<=>n]
puts v + v.reverse
}
}

Usage:

->n{s=1,1;3.upto(n){s<<s[-1]+s[-2]};s.map!{|i|[' ']*(s[-1]-i)+[?i]*i}.transpose.map!{|a|v=a*'_ '[a.count(?i)<=>n];puts v+v.reverse}}[8]

Output:

ii
ii
ii
ii
ii
ii
ii
ii
i ii i
i ii i
i ii i
i ii i
i ii i
i i ii i i
i i ii i i
i i ii i i
i i i ii i i i
i i i ii i i i
i i i i ii i i i i
i i i i i ii i i i i i
i_i_i_i_i_i_i_ii_i_i_i_i_i_i_i

# Python 2, 213

Saved 12 bytes thanks to DSM.

def f(r):
a=b=1
while r:yield a;a,b=b,a+b;r-=1
n=list(f(input()))
n.remove(1)
h=max(n)-1
r=1
while h:
l='  '*(len(n)+1)+('i '*r)[:-1];print(l+l[::-1]);h-=1
if h in n:r+=1;n.pop()
l='i_'*r+'i_i'
print l+l[::-1]

Ungolfed version.

max_height = input()
def fib(r):
a=b=1
while r:
yield a
a,b = b, a + b
r-=1

numbers = [x for x in fib(max_height) if x>1]
highest = max(numbers) -1
rows = 1
while highest:
line =' '*((len(numbers)+1)*2) + ' '.join('i'*rows)
print(line + line[::-1])
highest -= 1
if highest in numbers:
rows += 1
numbers.pop()

line = '_'.join('i'*(rows+2))
print(line + line[::-1])