5
\$\begingroup\$

Given a number n, you must output a golden spiral with the number of quarter turns being n.

The spiral must be completely black and the background must be completely white. This must be output as a φ⌊n/4⌋*4 by φ⌊n/4⌋*4 PNG file (you may output a PPM and convert it later). The shortest code wins.

The radius of the smallest quarter turn should be φ-3.

In geometry, a golden spiral is a logarithmic spiral whose growth factor is φ, the golden ratio.That is, a golden spiral gets wider (or further from its origin) by a factor of φ for every quarter turn it makes.

\$\endgroup\$
7
  • 3
    \$\begingroup\$ So, this is actually Draw a black golden spiral then? \$\endgroup\$
    – Compass
    Oct 17 '14 at 17:59
  • 5
    \$\begingroup\$ @Compass You should draw it with coffee or oil, probably, but there are other options. \$\endgroup\$
    – Geobits
    Oct 17 '14 at 18:01
  • 1
    \$\begingroup\$ @Geobits Just don't use Marmite \$\endgroup\$ Oct 17 '14 at 18:17
  • 1
    \$\begingroup\$ If someone was to use blockly, would they have to screen-shot their code? How would byte-count be decided? For the curious, the turtle is shown drawing what looks at a glance like the golden spiral: blockly-demo.appspot.com/static/apps/index.html?lang=en \$\endgroup\$
    – Will
    Oct 17 '14 at 18:44
  • 2
    \$\begingroup\$ @Will That's not a golden spiral in the icon, it's not even a logarithmic spiral. It's an arithmetic/archimedian spiral (that grows by the same amount each revolution.) A golden spiral is a type of logarithmic spiral (that grows by the same ratio each revolution.) Another characteristic of a logarithmic spiral is that for any point on the spiral there is a constant angle between the radius passing through that point and the spiral itself, so the spiral looks the same when you zoom in or out. I can't get the blockly sample program to run, though. \$\endgroup\$ Oct 17 '14 at 18:56
7
\$\begingroup\$

Mathematica, 169 bytes

All those annoying options. :(

f=Export[p=GoldenRatio;"a.png",ParametricPlot[p^(2t-3){Cos[a=t*Pi],Sin@a},{t,0,#/2},PlotRange->{r={m=-p^(#-3),-m},r},PlotStyle->Black,Axes->1<0,ImageSize->p^#~Floor~4]]&

This function saves the spiral to a.png in wherever your current working directory is.

The result of f[9]:

enter image description here

The result of f[12]:

enter image description here

I hope I understood all the bits about the scaling correctly.

There's not a whole lot to say about the code. I'm using ParametricPlot to draw curve as a parameterised function in t which advances by 1/2 for each quarter turn. The rest is done in the options:

  • PlotRange->{r={m=-p^(#-3),-m},r} makes sure we have an square aspect ratio which just covers the outermost point of the spiral.
  • PlotStyle->Black overwrites Mathematica's blue default colour.
  • Axes->1<0 is just Axes->False (and turns off the axes, who knew!).
  • ImageSize->p^#~Floor~4 sets the correct dimensions in pixels, by noticing that ⌊n/4⌋*4 just means "n rounded down to the nearest multiple of 4".
\$\endgroup\$
3
  • \$\begingroup\$ Hmm... I think it could perhaps be slightly shorter as a PolarPlot, but it probably wouldn't differ too much. \$\endgroup\$
    – Tally
    Oct 18 '14 at 23:11
  • \$\begingroup\$ @Tally Ah, I keep forgetting about PolarPlot. I'll have a look at that later. \$\endgroup\$ Oct 20 '14 at 11:11
  • 2
    \$\begingroup\$ What? Mathematica doesn't have GoldenSpiral[]? I'm dissapoint \$\endgroup\$
    – BrunoJ
    Oct 20 '14 at 14:58
6
\$\begingroup\$

Python 3 - 290 269

This will get crushed by any kind of built-in parametrics, but I figured I'd post it as an example of a point-by-point solution.

Edit: Thanks for the golfing tips! If you have any more, please make them.

from math import *
from PIL import Image as I, ImageDraw as D
n=eval(input())
G=(1+5**.5)/2
w=int(G**(4*(n//4)))
i=I.new("RGB",(w,w),"white")
d=D.Draw(i)
k=pi/180
d.line([(G**(j/90)*cos(j*k)+w/2,G**(j/90)*sin(j*k)+w/2)for j in range(n*90)],fill=0)
i.save("s.png","PNG")
\$\endgroup\$
4
  • \$\begingroup\$ You can really golf this down. You can from math import * to avoid the M. prefix everywhere and you can turn the for loop into a comprehension. However, when I run this, I had to remove the eval() on the input() for entering a number, and I couldn't get the expected graph for the size. Setting n to a big number like 10 or 20 and it never finishes; setting it to a bigger number like 50 and it immediately aborts because the numbers are too big. \$\endgroup\$
    – Will
    Oct 18 '14 at 15:22
  • \$\begingroup\$ Thanks for the tips, Will! I'm not sure how to make it work for large n, as the requirements specify an exponential image size. \$\endgroup\$
    – R.T.
    Oct 18 '14 at 22:34
  • \$\begingroup\$ You can create your image like so if you only use B&W : i=I.new('L',(w,w)) and display it with i.show(). \$\endgroup\$ Oct 19 '14 at 15:52
  • \$\begingroup\$ Can shave off two bytes by changing from math import * to from math import* and from PIL import Image as I, ImageDraw as D to from PIL import Image as I,ImageDraw as D \$\endgroup\$
    – globby
    Oct 20 '14 at 23:58

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.