21
\$\begingroup\$

Background

Today (or Yesterday) 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
\$\endgroup\$
14
  • 9
    \$\begingroup\$ 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 \$\endgroup\$
    – cat
    Commented Nov 24, 2015 at 3:01
  • 1
    \$\begingroup\$ @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 \$\endgroup\$
    – Downgoat
    Commented Nov 24, 2015 at 3:05
  • 6
    \$\begingroup\$ This challenge is going to be legendary in 43 years (11/23/58). \$\endgroup\$
    – Arcturus
    Commented Nov 24, 2015 at 4:43
  • 11
    \$\begingroup\$ In 43 years the mm/dd/yy date format will be history. All intelligent beings will have switched to yyyy/mm/dd... :-P \$\endgroup\$
    – user19214
    Commented Nov 24, 2015 at 5:18
  • 2
    \$\begingroup\$ @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. \$\endgroup\$ Commented Nov 24, 2015 at 9:33

11 Answers 11

6
\$\begingroup\$

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.

\$\endgroup\$
5
\$\begingroup\$

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.
\$\endgroup\$
3
\$\begingroup\$

TeaScript, 93 84 76 + 1 = 77 bytes

+1 byte for "Inputs are numbers?" checkbox

r×ß(p.R((w=F(x©-F(i¬©+"i"R(F(i¬±)t¡ß(j=i<w-1?" ":"_",(A=l¿i>0?j+l:l)µ)+Av©j§

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.

\$\endgroup\$
8
  • \$\begingroup\$ You should be able to use the r function instead of A(x)f(0), e.g. r(x)m(# \$\endgroup\$
    – Downgoat
    Commented Nov 24, 2015 at 3:46
  • \$\begingroup\$ @Vɪʜᴀɴ Thanks. What does Array.dupe() do, it doesn't seem to work? \$\endgroup\$ Commented Nov 24, 2015 at 3:49
  • \$\begingroup\$ Array.dupe was probably a bad name, it removes duplicates from an array. \$\endgroup\$
    – Downgoat
    Commented Nov 24, 2015 at 3:49
  • \$\begingroup\$ @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. \$\endgroup\$ Commented Nov 24, 2015 at 3:56
  • 1
    \$\begingroup\$ @sysreq I meant ungolfed, sorry for the confusion. \$\endgroup\$ Commented Nov 24, 2015 at 14:07
3
\$\begingroup\$

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.

\$\endgroup\$
2
+50
\$\begingroup\$

Pyth, 31 bytes

jaPJ_.ts_BuaaGks>4GtQ]\idXeJ" _

Try it online: Demonstration

Explanation:

jaPJ_.ts_BuaaGks>4GtQ]\idXeJ" _   implicit: Q = input number
          u        tQ]\i          reduce the list [1, ..., Q-2], start with G=["i"]
            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
\$\endgroup\$
2
\$\begingroup\$

Haskell, 182 176 bytes

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)

\$\endgroup\$
2
  • \$\begingroup\$ You can replace flip replicate 'i'.(f!!) by \x->[1..f!!x]>>"i". \$\endgroup\$
    – nimi
    Commented Nov 27, 2015 at 14:39
  • \$\begingroup\$ 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... \$\endgroup\$ Commented Nov 28, 2015 at 1:49
2
\$\begingroup\$

Jelly, 23 bytes

RÆḞ”iẋz⁶Ḣj”_ƊṭK€Ṛ$Ɗm€0Y

Try it online!

Jelly's not great at and neither am I

How it works

RÆḞ”iẋz⁶Ḣj”_ƊṭK€Ṛ$Ɗm€0Y - Main link. Takes N on the left
R                       - [1, 2, ..., N]
 ÆḞ                     - k'th Fibonacci for each k in the range
   ”i                   - "i"
     ẋ                  - Repeat "i" k times for each k
      z⁶                - Transpose filling with spaces
                  Ɗ     - To this matrix:
            Ɗ           -   First:
        Ḣ               -     Pop and yield the first element (the base)
         j”_            -     Join with "_"
                 $      -   Then:
              K€        -     Join the other rows on spaces
                Ṛ       -     Reverse
             ṭ          -   Take the base onto the end of the rows
                   m€0  - Mirror each row
                      Y - Join on newlines
\$\endgroup\$
1
\$\begingroup\$

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)]
\$\endgroup\$
1
\$\begingroup\$

Ruby, 151 146 142 137 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
\$\endgroup\$
1
\$\begingroup\$

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])
\$\endgroup\$
1
\$\begingroup\$

Vyxal, 21 bytes

v∆F\i*∩vṄṘøɽvm‡\_ḞuV⁋

Try it Online!

How?

v∆F\i*∩vṄṘøɽvm‡\_ḞuV⁋
v∆F                   # For each item in [1, implicit input], get the nth fibonacci number
   \i*                # For each, repeat that many "i"s
      ∩               # Transpose
       vṄ             # Join each by spaces
         Ṙ            # Reverse
          øɽ          # Prepend leading spaces to each to right-align it
            vm        # Mirror each
              ‡\_ḞuV  # To the last item, replace spaces with "_"
                    ⁋ # Join on newlines
\$\endgroup\$

Your Answer

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

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