Fibonacci Spiral

37

5

Your goal is to generate a Fibonacci spiral with numbers.

Sample

Example Input / Output

1 -> 1

2 -> 1 1

3 -> 1 1
     2 2
     2 2

6 -> 8 8 8 8 8 8 8 8 5 5 5 5 5
     8 8 8 8 8 8 8 8 5 5 5 5 5
     8 8 8 8 8 8 8 8 5 5 5 5 5
     8 8 8 8 8 8 8 8 5 5 5 5 5
     8 8 8 8 8 8 8 8 5 5 5 5 5
     8 8 8 8 8 8 8 8 1 1 3 3 3
     8 8 8 8 8 8 8 8 2 2 3 3 3
     8 8 8 8 8 8 8 8 2 2 3 3 3

Input of 9

Input The input can be taken through STDIN or function argument. It will be a single number

Output The output can be from STDOUT or a function's return value. It should be a single string.

Extra whitespace at the very end of the line is not allowed. The output can contain digits, linefeeds (newlines), and spaces.

Orientation does not matter, this means rotations and reflections. As long as it follows a valid Fibonacci spiral pattern.

Numbers with different amounts of digits (e.g. 1 and 13) should be right-aligned with each other. A space may need to be added to the very beginning of a line so everything can line up.

1   1                          1   1
100 100  should actually be  100 100

You can see an example here


This is so shortest code in bytes wins!

Downgoat

Posted 2015-07-18T21:02:52.730

Reputation: 27 116

4Related challenge (and a very cool clock) – Sp3000 – 2015-07-18T21:19:22.857

Numbers with different amounts of digits (e.g. 1 and 13) should be aligned to the left side of the digit a space may need to be added to the very beginning of a line so everything can line up. This sounds like it might be clearer as two sentences. – trichoplax – 2015-07-18T21:42:10.040

It looks from the examples that you want the rightmost digit of each number to be aligned, but "aligned to the left side of the digit" sounds like the opposite. – trichoplax – 2015-07-18T21:43:38.703

Can you clarify "surrounding whitespace is not allowed"? In particular - is leading or trailing whitespace on the lines acceptable? – MtnViewMark – 2015-07-19T11:51:55.637

Matlab prints output to stdout by default. Is it acceptable to have numeric-type output (as opposed to string-type output) that gets automatically printed to stdout? – Luis Mendo – 2015-07-19T13:06:16.067

Answers

15

APL, 23

{a,⍴⍨2⍴⊃⍴a←⌽⍉⍵}⍣(⎕-1)⍪1

Explanation:

⍪1               this creates a 1x1 matrix containing just 1
{..}⍣(⎕-1)     the power operator (⍣) repeats the function {} user input - 1 times
a,⍴⍨2⍴⊃⍴a←⌽⍉⍵   the function being iterated rotates the matrix and appends the next matrix to it.

Try it on tryapl.org

Moris Zucca

Posted 2015-07-18T21:02:52.730

Reputation: 1 519

1If you search here, many had your doubt before. Here is for example @Tobia 's answer: * Dyalog APL supports a legacy charset which has the APL symbols mapped to the upper 128 byte values. Therefore an APL program that only uses ASCII characters and APL symbols can be considered to be bytes == chars. – Moris Zucca – 2015-07-21T07:29:35.687

Okay then, I'll retract my comment. – gar – 2015-07-21T07:46:07.627

1@MorisZucca Notice though, that some characters (like or ) are missing from that character set and cannot be used when you want to evoke that rule. – FUZxxl – 2015-07-22T10:40:07.753

1True, "key" and "rank" are newer implementations and exist in fact only in the Unicode version of the Dyalog interpreter I use. The Classic version has to use the ⎕command equivalent. The same applies to ⍠ (⎕OPT) too for example. Thus I usually think that if I can write it in the Dyalog Classic version, it's safe to say it's 1 byte per char. Correct me if I'm wrong. And thanks for the comment. – Moris Zucca – 2015-07-22T12:12:44.727

8

Matlab, 84 bytes

A function is used. Output is in stdout.

function f(N)
s=0;t=1;y=1;for n=2:N
u=s+t;s=t;t=u;y=[rot90(y) t*ones(t)];end;disp(y)

Examples:

>> f(1)
     1
>> f(2)
     1     1
>> f(3)
     1     2     2
     1     2     2
>> f(6)
     5     5     5     5     5     8     8     8     8     8     8     8     8
     5     5     5     5     5     8     8     8     8     8     8     8     8
     5     5     5     5     5     8     8     8     8     8     8     8     8
     5     5     5     5     5     8     8     8     8     8     8     8     8
     5     5     5     5     5     8     8     8     8     8     8     8     8
     3     3     3     1     1     8     8     8     8     8     8     8     8
     3     3     3     2     2     8     8     8     8     8     8     8     8
     3     3     3     2     2     8     8     8     8     8     8     8     8
>> f(7)
     8     8     8     8     8     8     8     8    13    13    13    13    13    13    13    13    13    13    13    13    13
     8     8     8     8     8     8     8     8    13    13    13    13    13    13    13    13    13    13    13    13    13
     8     8     8     8     8     8     8     8    13    13    13    13    13    13    13    13    13    13    13    13    13
     8     8     8     8     8     8     8     8    13    13    13    13    13    13    13    13    13    13    13    13    13
     8     8     8     8     8     8     8     8    13    13    13    13    13    13    13    13    13    13    13    13    13
     8     8     8     8     8     8     8     8    13    13    13    13    13    13    13    13    13    13    13    13    13
     8     8     8     8     8     8     8     8    13    13    13    13    13    13    13    13    13    13    13    13    13
     8     8     8     8     8     8     8     8    13    13    13    13    13    13    13    13    13    13    13    13    13
     5     5     5     5     5     1     2     2    13    13    13    13    13    13    13    13    13    13    13    13    13
     5     5     5     5     5     1     2     2    13    13    13    13    13    13    13    13    13    13    13    13    13
     5     5     5     5     5     3     3     3    13    13    13    13    13    13    13    13    13    13    13    13    13
     5     5     5     5     5     3     3     3    13    13    13    13    13    13    13    13    13    13    13    13    13
     5     5     5     5     5     3     3     3    13    13    13    13    13    13    13    13    13    13    13    13    13

Matlab, 78 bytes

function y=f(N)
s=0;t=1;y=1;for n=2:N
u=s+t;s=t;t=u;y=[rot90(y) t*ones(t)];end

Same as above except a Matlab's feature is exploited, namely, it automatically displays function output (as a string) in stdout. This avoids the conversion to string in the above approach.

f(6)
ans =
     5     5     5     5     5     8     8     8     8     8     8     8     8
     5     5     5     5     5     8     8     8     8     8     8     8     8
     5     5     5     5     5     8     8     8     8     8     8     8     8
     5     5     5     5     5     8     8     8     8     8     8     8     8
     5     5     5     5     5     8     8     8     8     8     8     8     8
     3     3     3     1     1     8     8     8     8     8     8     8     8
     3     3     3     2     2     8     8     8     8     8     8     8     8
     3     3     3     2     2     8     8     8     8     8     8     8     8

Luis Mendo

Posted 2015-07-18T21:02:52.730

Reputation: 87 464

glad to see some Matlab solutions :-) – Hoki – 2015-07-20T08:57:23.207

@Hoki Thanks! :-) – Luis Mendo – 2015-07-20T11:02:50.310

7

Ruby, 243 242 236 233 222 170 130 bytes

s,l,r=0,1,[]
gets.to_i.times{s+=l
l=s-l
s.times{r<<[s]*s}
r=r.transpose.reverse}
r.map{|w|puts w.map{|c|"%#{s.to_s.size}s"%c}*" "}

addison

Posted 2015-07-18T21:02:52.730

Reputation: 993

1Nice golfing! You can save some chars on line 4, by converting t==value conditions to t>value. For example, (t=x%4)>2?s.times{r<<[s]*s}:t>1?s.times{r.map!{|w|w.unshift s}}:t>0?s.times{r.unshift [s]*s}:r.map!{|w|w+=[s]*s}} – Cristian Lupascu – 2015-07-19T08:00:37.440

7

Python 2, 121 bytes

a,b=0,1;L=[]
exec"a,b=b,a+b;L=zip(*L[::-1])+[[a]*a]*a;"*input()
for r in L:print" ".join("%*d"%(len(str(a)),x)for x in r)

The relaxed rules on rotations makes this a lot simpler.

I haven't used backticks in place of str(a) here because I'm not sure whether we're allowed more leading spaces than necessary, if we ever reach longs. Although, even if we were, using a itself would be shorter anyway.

Sp3000

Posted 2015-07-18T21:02:52.730

Reputation: 58 729

6

Python - 189 179 174

n=int(input())
f=[1,1]
while len(f)<n:f+=[f[-1]+f[-2]]
o=[[]]
for i in f:o=(list(zip(*o)))[::-1]+[[i]*i]*i
for x in o:print(' '.join(str(y).rjust(len(str(f[-1])))for y in x))

faubi

Posted 2015-07-18T21:02:52.730

Reputation: 2 599

6

Haskell, 183 176 171 163 bytes

import Data.List
s t=map((t>>[l t])++)t
e 1=[[1]];e n=s.reverse.transpose$e$n-1
f=g.e
g m=unlines$map(>>=((show$l m)#).show)m
a#b|l a<l b=b;a#b=a#(' ':b)
l=length

The function is f, which takes a number and returns a single string:

λ: putStr $ f 8
 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21  5  5  5  5  5  8  8  8  8  8  8  8  8
 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21  5  5  5  5  5  8  8  8  8  8  8  8  8
 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21  5  5  5  5  5  8  8  8  8  8  8  8  8
 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21  5  5  5  5  5  8  8  8  8  8  8  8  8
 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21  5  5  5  5  5  8  8  8  8  8  8  8  8
 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21  3  3  3  1  1  8  8  8  8  8  8  8  8
 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21  3  3  3  2  2  8  8  8  8  8  8  8  8
 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21  3  3  3  2  2  8  8  8  8  8  8  8  8
 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 13 13 13 13 13 13 13 13 13 13 13 13 13
 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 13 13 13 13 13 13 13 13 13 13 13 13 13
 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 13 13 13 13 13 13 13 13 13 13 13 13 13
 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 13 13 13 13 13 13 13 13 13 13 13 13 13
 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 13 13 13 13 13 13 13 13 13 13 13 13 13
 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 13 13 13 13 13 13 13 13 13 13 13 13 13
 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 13 13 13 13 13 13 13 13 13 13 13 13 13
 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 13 13 13 13 13 13 13 13 13 13 13 13 13
 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 13 13 13 13 13 13 13 13 13 13 13 13 13
 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 13 13 13 13 13 13 13 13 13 13 13 13 13
 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 13 13 13 13 13 13 13 13 13 13 13 13 13
 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 13 13 13 13 13 13 13 13 13 13 13 13 13
 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 13 13 13 13 13 13 13 13 13 13 13 13 13

MtnViewMark

Posted 2015-07-18T21:02:52.730

Reputation: 4 779

6

J, 36 bytes

1&(($~,~)@(1{$@]),.|:@|.@])&(,.1)@<:

Usage:

   (1&(($~,~)@(1{$@]),.|:@|.@])&(,.1)@<:) 6
8 8 8 8 8 8 8 8 5 5 5 5 5
8 8 8 8 8 8 8 8 5 5 5 5 5
8 8 8 8 8 8 8 8 5 5 5 5 5
8 8 8 8 8 8 8 8 5 5 5 5 5
8 8 8 8 8 8 8 8 5 5 5 5 5
8 8 8 8 8 8 8 8 1 1 3 3 3
8 8 8 8 8 8 8 8 2 2 3 3 3
8 8 8 8 8 8 8 8 2 2 3 3 3

Method:

The function rotates the current square and adds the new square to the current one input-1 times. Square size and element values are gathered from the size of the previous rectangle.

Code explanation:

1&(           loop
    ($~,~)      new square with size and elements
    @(1{$@])    with the size of the second dimension of the current rectangle
    ,.          attached to
    |:@|.@]     rotated current rectangle
)&(,.1)       starting the loop with matrix 1
@<:           looping input-1 times

Try it online here.

randomra

Posted 2015-07-18T21:02:52.730

Reputation: 19 909

5

Pyth, 34 bytes

jbmsm.[hl`lhZ`k\ d=Zu+_CGmmlGGGQ]]

Surprisingly, more than half of the code is printing/padding, rather than generating the matrix.

The generation of the matrix is really simple however, it consists of a transpose and reversal, and adding N lines containing N copies of N, where N is the current number of lines.

Example output for 7:

  5  5  5  5  5  8  8  8  8  8  8  8  8
  5  5  5  5  5  8  8  8  8  8  8  8  8
  5  5  5  5  5  8  8  8  8  8  8  8  8
  5  5  5  5  5  8  8  8  8  8  8  8  8
  5  5  5  5  5  8  8  8  8  8  8  8  8
  3  3  3  1  1  8  8  8  8  8  8  8  8
  3  3  3  2  2  8  8  8  8  8  8  8  8
  3  3  3  2  2  8  8  8  8  8  8  8  8
 13 13 13 13 13 13 13 13 13 13 13 13 13
 13 13 13 13 13 13 13 13 13 13 13 13 13
 13 13 13 13 13 13 13 13 13 13 13 13 13
 13 13 13 13 13 13 13 13 13 13 13 13 13
 13 13 13 13 13 13 13 13 13 13 13 13 13
 13 13 13 13 13 13 13 13 13 13 13 13 13
 13 13 13 13 13 13 13 13 13 13 13 13 13
 13 13 13 13 13 13 13 13 13 13 13 13 13
 13 13 13 13 13 13 13 13 13 13 13 13 13
 13 13 13 13 13 13 13 13 13 13 13 13 13
 13 13 13 13 13 13 13 13 13 13 13 13 13
 13 13 13 13 13 13 13 13 13 13 13 13 13
 13 13 13 13 13 13 13 13 13 13 13 13 13

orlp

Posted 2015-07-18T21:02:52.730

Reputation: 37 067

4

Perl, 289 277 257 bytes

@f=(0,1);push@f,$f[-1]+$f[-2]while(@f<=$ARGV[0]);$d=1+length$f[-1];shift@f;map{$v=$f[$_];$t=sprintf("%${d}d",$v)x$v;$_%4||map{unshift@s,$t}1..$v;$_%4==3&&map{$_.=$t}@s;$_%4==2&&map{push@s,$t}1..$v;$_%4==1&&map{$_=$t.$_}@s;}0..$#f;$\=$/;for(@s){s/^ //;print}

Ruth Franklin

Posted 2015-07-18T21:02:52.730

Reputation: 760

4

K, 48 bytes

{{`0:1_',/'(1+#$|//x)$x}(x-1){+|x,\:t#t:#x}/,,1}

And in action:

  {{`0:1_',/'(1+#$|//x)$x}(x-1){+|x,\:t#t:#x}/,,1}7
 8  8  8  8  8  8  8  8  5  5  5  5  5
 8  8  8  8  8  8  8  8  5  5  5  5  5
 8  8  8  8  8  8  8  8  5  5  5  5  5
 8  8  8  8  8  8  8  8  5  5  5  5  5
 8  8  8  8  8  8  8  8  5  5  5  5  5
 8  8  8  8  8  8  8  8  1  1  3  3  3
 8  8  8  8  8  8  8  8  2  2  3  3  3
 8  8  8  8  8  8  8  8  2  2  3  3  3
13 13 13 13 13 13 13 13 13 13 13 13 13
13 13 13 13 13 13 13 13 13 13 13 13 13
13 13 13 13 13 13 13 13 13 13 13 13 13
13 13 13 13 13 13 13 13 13 13 13 13 13
13 13 13 13 13 13 13 13 13 13 13 13 13
13 13 13 13 13 13 13 13 13 13 13 13 13
13 13 13 13 13 13 13 13 13 13 13 13 13
13 13 13 13 13 13 13 13 13 13 13 13 13
13 13 13 13 13 13 13 13 13 13 13 13 13
13 13 13 13 13 13 13 13 13 13 13 13 13
13 13 13 13 13 13 13 13 13 13 13 13 13
13 13 13 13 13 13 13 13 13 13 13 13 13
13 13 13 13 13 13 13 13 13 13 13 13 13

May still be some good opportunities for golfing.

The program basically consists of two parts- generating the concatenated matrix and formatting it for output. The former is fairly simple:

  {(x-1){+|x,\:t#t:#x}/,,1}5
(3 3 3 2 2
 3 3 3 2 2
 3 3 3 1 1
 5 5 5 5 5
 5 5 5 5 5
 5 5 5 5 5
 5 5 5 5 5
 5 5 5 5 5)

Beginning with a 1x1 matrix containing 1, build a T-length vector of T where T is the length of the starting matrix on the first dimension (t#t:#x) and attach that to each row of the original matrix (x,\:). Reversing and transposing the result (+|) rotates it 90 degrees. We do this N-1 times.

Formatting is pretty clunky, because K's natural approach to printing a matrix won't align number columns the way we need:

{`0:1_',/'(1+#$|//x)$x}

The basic idea is to take the maximum element of the matrix (|//x), convert it to a string (unary $), take its length plus one (1+#) and then format the elements of the matrix to right aligned strings of that size. Then to tidy up, join those strings (,/') and drop the resulting leading space (1_').

JohnE

Posted 2015-07-18T21:02:52.730

Reputation: 4 632

4

CJam, 48 bytes

1saali({z{W%}%_0=,__sa*a*+}*_W=W=,):U;{USe[}f%N*

Try it online

The core part of generating the pattern seems reasonably straightforward. Rotate the rectangle created so far, and add a square of values at the bottom.

The code for padding the result looks awful, though. I tried a bunch of combinations of f and : operators to apply the padding to the nested list, but nothing worked. If anybody has better suggestions, they are most welcome.

1s    First value. Using string for values so that we can pad them in the end.
aa    Wrap it twice. Data on stack will be a list of lists (list of lines).
li    Get input.
(     Decrement, since we seeded the list at n=1.
{     Loop over n.
  z     Transpose...
  {W%}% ... and reverse all lines, resulting in a 90 degree rotation.
  _0=,  Get length of line, which is the size of square we need to add.
  __    Create two copies of size.
  sa    Convert one size to string, and wrap it in array.
  *     Replicate it size times. This is one line.
  a     Wrap the line...
  *     ... and replicate it size times. The square of new values is done.
  +     Add the list of lines to the previous list of lines.
}*    End of loop over n.
_W=W= Get last value produced.
,)    Take its length, and increment it. This is the output field width.
:U;   Store the field width in variable, and pop it. This is ugly.
{     Start of block applied to all values.
  U     Field width stored in variable.
  S     Space.
  e[    Pad left.
}f%   End of block applied to all values.
N*    Join lines with newline.

Reto Koradi

Posted 2015-07-18T21:02:52.730

Reputation: 4 870

Reversing all lines can be done with Wf%. Also, would you be able to do something like {Se[}ff% rather than :U;{USe[}f% for the padding? (That might not work as it is, I can't think through it right now.) – Esolanging Fruit – 2017-04-23T05:59:24.853

2

Pyth, 29 bytes

Vu+C_GmmlGGGQ\]Yjdm.\[l`lN`d\ N

Demonstration.

If padding was free/implicit, like in APL, or matrix output was allowed, this would be 14 bytes:

u+C_GmmlGGGQ]Y

isaacg

Posted 2015-07-18T21:02:52.730

Reputation: 39 268

2

Ruby, 129 bytes

I edited the other ruby answer a bunch, but my most recent change is not being accepted or something, so here it is:

s,r=0,[[1]]
gets.to_i.times{s+=r[0][0]
r=(r+[[s]*s]*s).transpose.reverse}
r.map{|w|puts w.map{|c|"%#{r[0][s].to_s.size}s"%c}*' '}

user2251284

Posted 2015-07-18T21:02:52.730

Reputation: 127

1

Welcome to PPCG! Golfing improvements are usually rejected around here (if your other suggestions were accepted that must have been an oversight), because they are supposed to be posted in comments for the author to review. See this meta post for the reasoning behind this policy.

– Martin Ender – 2015-07-24T11:52:32.937

Thanks for the info, makes sense. Commenting is what I would have originally done but I did not have enough reputation points to comment, but will do in the future. Happy golfing! – user2251284 – 2015-07-24T15:02:03.417

1

ES6, 248 bytes

n=>(f=(n,o=n)=>Array(n).fill(o),g=n=>n<3?[f(n,1)]:(a=g(n-2)).reverse().concat(f(l=a[0].length,f(l))).map((e,i,a)=>f(a.length).concat(e.reverse())),a=g(n),s=' '.repeat(l=` ${a[0][0]}`.length),a.map(a=>a.map((e,i)=>(s+e).slice(!i-1)).join``).join`\n`)

Where \n represents a literal newline character.

Annoyingly the formatting takes up a large chunk of the code.

f is a helper function that makes a filled array. It's used mostly to create the filled squares but also handily doubles up to produce the base cases for the recursion.

g is the main gruntwork. It recursively generates the last but one solution, rotates it 180 degrees, then appends the next two squares.

Neil

Posted 2015-07-18T21:02:52.730

Reputation: 95 035