37
\$\begingroup\$

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!

\$\endgroup\$
  • 4
    \$\begingroup\$ Related challenge (and a very cool clock) \$\endgroup\$ – Sp3000 Jul 18 '15 at 21:19
  • \$\begingroup\$ 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. \$\endgroup\$ – trichoplax Jul 18 '15 at 21:42
  • \$\begingroup\$ 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. \$\endgroup\$ – trichoplax Jul 18 '15 at 21:43
  • \$\begingroup\$ Can you clarify "surrounding whitespace is not allowed"? In particular - is leading or trailing whitespace on the lines acceptable? \$\endgroup\$ – MtnViewMark Jul 19 '15 at 11:51
  • \$\begingroup\$ 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? \$\endgroup\$ – Luis Mendo Jul 19 '15 at 13:06

14 Answers 14

15
\$\begingroup\$

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

\$\endgroup\$
  • 1
    \$\begingroup\$ If 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. \$\endgroup\$ – Moris Zucca Jul 21 '15 at 7:29
  • \$\begingroup\$ Okay then, I'll retract my comment. \$\endgroup\$ – gar Jul 21 '15 at 7:46
  • 1
    \$\begingroup\$ @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. \$\endgroup\$ – FUZxxl Jul 22 '15 at 10:40
  • 1
    \$\begingroup\$ True, "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. \$\endgroup\$ – Moris Zucca Jul 22 '15 at 12:12
8
\$\begingroup\$

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
\$\endgroup\$
  • \$\begingroup\$ glad to see some Matlab solutions :-) \$\endgroup\$ – Hoki Jul 20 '15 at 8:57
  • \$\begingroup\$ @Hoki Thanks! :-) \$\endgroup\$ – Luis Mendo Jul 20 '15 at 11:02
7
\$\begingroup\$

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.

\$\endgroup\$
7
\$\begingroup\$

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}*" "}
\$\endgroup\$
  • 1
    \$\begingroup\$ Nice 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}} \$\endgroup\$ – Cristian Lupascu Jul 19 '15 at 8:00
6
\$\begingroup\$

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

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.

\$\endgroup\$
6
\$\begingroup\$

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

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

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}
\$\endgroup\$
4
\$\begingroup\$

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_').

\$\endgroup\$
4
\$\begingroup\$

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.
\$\endgroup\$
  • \$\begingroup\$ 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.) \$\endgroup\$ – Esolanging Fruit Apr 23 '17 at 5:59
2
\$\begingroup\$

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

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}*' '}
\$\endgroup\$
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ – Martin Ender Jul 24 '15 at 11:52
  • \$\begingroup\$ 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! \$\endgroup\$ – user2251284 Jul 24 '15 at 15:02
1
\$\begingroup\$

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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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