12
\$\begingroup\$

Overview

I was playing with Desmos and discovered a really cool spiral:

Archimedian Spiral

Doing some research, I discovered that this spiral was the Archimedian spiral. Every point on the spiral is exactly \$\theta\$ away from the origin, where \$\theta\$ is the angle from the origin. That is, any point on the spiral has the polar coordinates \$(\theta, \theta)\$. This also has the consequence that the shortest distance between 2 arms of the spiral is exactly \$2\pi\$ if using radians or \$360\$ if using degrees.

The Challenge

The basic spiral can be defined by the following formula in the polar coordinate system: $$ r = a\theta $$ Where \$a\$ is the multiplier of the distance between the arms. Your job is, given a floating point input for \$a\$, draw this spiral with at least one full rotation. You may output the image according to any image I/O defaults.

Scoring

This is , shortest answer in bytes wins.

\$\endgroup\$
2
  • 6
    \$\begingroup\$ You may use either degrees or radians for \$\theta\$, but not anything else. Does it really matter? Unless we are required to draw the axis and make the scale explicit, this looks like a non-observable requirement. \$\endgroup\$
    – Arnauld
    May 13, 2022 at 17:47
  • \$\begingroup\$ @Arnauld I guess that's a fair point \$\endgroup\$
    – Seggan
    May 13, 2022 at 18:07

14 Answers 14

10
\$\begingroup\$

Minecraft Command Blocks, 599 bytes

command block pic

Commands

Left column (bottom block 0, 4, -2)

scoreboard objectives add c dummy
scoreboard players set m c 1
summon armor_stand 0 0 0
setblock 0 3 0 redstone_block

Middle column (bottom block 0, 4, 0)

execute at @e[type=armor_stand] run setblock ~ ~ ~ stone
tp @e[type=armor_stand] 0 0 0
execute as @e[type=armor_stand] at @s run tp @s ~ ~ ~ ~5 ~
scoreboard players reset d
scoreboard players add m c 1
setblock 0 3 1 air
setblock 0 3 1 redstone_block

Right column (bottom block 0, 4, 1)

execute as @e[type=armor_stand] at @s run tp @s ^ ^ ^<Input>
scoreboard players add d c 1
setblock 0 3 1 air
setblock 0 3 0 air
execute unless score d c = m c run setblock 0 3 1 redstone_block
execute if score d c = m c run setblock 0 3 0 redstone_block

The distance multiplier is set in the first command block in the right column. Hardcoding inputs is not allowed by codegolf rules, but there isn't any other way to take input in Minecraft.

When ran for an hour with an input of 0.1 it produced this. It starts skipping blocks after a little over one rotation but it does complete one full rotation. spiral

\$\endgroup\$
3
  • \$\begingroup\$ does tp @s ^ ^ ^<Input> cause the armour stand to rotate? \$\endgroup\$
    – user253751
    May 16, 2022 at 8:58
  • \$\begingroup\$ Nice one! Minecraft answers seem to be so rare in CGCC. \$\endgroup\$
    – Seggan
    May 16, 2022 at 15:33
  • \$\begingroup\$ @user253751 tp @s ^ ^ ^<Input> teleports the armor stand <Input> blocks in the direction it's facing. tp @s ~ ~ ~ ~5 ~ is the command that rotates it. \$\endgroup\$
    – LostXOR
    May 16, 2022 at 16:07
7
\$\begingroup\$

Desmos, 14 bytes

r=\ans_1\theta

Well...

Try it on Desmos!

\$\endgroup\$
3
  • \$\begingroup\$ Hardcoding the input in a variable (in your program, it's the variable a) is not allowed. A program that would better conform to the I/O standards set by the community would be r=\ans_1\theta, where the input number is placed in the second expression box. Try It On Desmos! \$\endgroup\$
    – Aiden Chow
    May 13, 2022 at 19:49
  • \$\begingroup\$ @AidenChow Forgot about \ans_0. Thanks \$\endgroup\$
    – naffetS
    May 13, 2022 at 19:53
  • \$\begingroup\$ Btw, you forgot edit this answer into the Desmos answers list here. \$\endgroup\$
    – Aiden Chow
    May 14, 2022 at 2:49
5
\$\begingroup\$

GFA-Basic 3.51 (Atari ST), 68 bytes

A manually edited listing in .LST format. All lines end with CR, including the last one.

PRO d(a)
F t=0TO 251
PL 160+t*COS(t/20)*a,100-t*SIN(t/20)*a
N t
RET

which expands to:

PROCEDURE d(a)
  FOR t=0 TO 251
    PLOT 160+t*COS(t/20)*a,100-t*SIN(t/20)*a
  NEXT t
RETURN

NB: We use \$251\$ as the upper bound so that the curve stops on the x-axis rather than at some random position (because \$251/20\approx 4\pi\$).

Example output

output

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

Wolfram Language (Mathematica), 22 bytes

PolarPlot[y#,{y,0,7}]&

Try it online!

I picked 7 for the plot range because it's a one-digit number that is close to \$2\pi\$ (so we get just around 1 rotation, slightly more).

Example result for input = 1:

example result

Example when we replace 7 with 50 (makes it more accurate to the image in the original post, but is one byte longer):

enter image description here

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

J, 28 bytes

plot@(**r.@o.@])(%~8*i.)@1e5

Try it online!

a=1 One

a=2 Two

\$\endgroup\$
3
\$\begingroup\$

R, 49 bytes

function(a)plot(cos(t<-0:9e3/1e3)*t*a,sin(t)*t*a)

Try it on rdrr.io!

\$\endgroup\$
4
  • \$\begingroup\$ I think a is supposed to be taken as input. \$\endgroup\$
    – Giuseppe
    May 13, 2022 at 18:55
  • \$\begingroup\$ @Giuseppe thanks, I somehow didn't notice this. \$\endgroup\$
    – pajonk
    May 13, 2022 at 19:06
  • \$\begingroup\$ @pajonk - I think you can get away with only 99 points per quadrant to save a byte... but using complex numbers gives even bigger savings... \$\endgroup\$ May 17, 2022 at 8:08
  • \$\begingroup\$ @DominicvanEssen hmm, I think I'll stick to the larger value, so it looks more like a line. The imaginary numbers idea - brilliant! \$\endgroup\$
    – pajonk
    May 17, 2022 at 8:17
3
\$\begingroup\$

BQN, 50 bytesSBCS

(•math.Sin•Plot○(⊢×↕∘≠)•math.Cos)-2×π×999⥊99÷˜↕100

Run online!

The JS version of BQN has a plotting builtin, which I used for the same rosetta code task. This is just a golf of that.

\$\endgroup\$
3
\$\begingroup\$

MATL, 13 bytes

9W:9/tJ*Ze*XG

Try it at MATL online!

Explanation

9W    % Push 9. 2 raised to that. Gives 512
:     % Range. Gives [1 2 ... 512] 
9/    % Divide each entry by 9
t     % Duplicate
J*    % Multiply each entry by imaginary unit
Ze    % Exponential of each entry
*     % Multiply each pair of entries
XG    % Plot
\$\endgroup\$
2
\$\begingroup\$

Excel & VBA, 144 bytes

Cell B1 = SEQUENCE(90)/9*PI()
Cell C1 = B1#*COS(B1#)*A1
Cell D1 = B1#*SIN(B1#)*A1
VBA Immediate Window Set x=activesheet.Shapes.AddChart2(,73,,,,360):x.Chart.SetSourceData Source:=Range("C1:D96")

Could cut the ,,,,360 if the plot doesn't have to be square. Excel Plot

\$\endgroup\$
1
  • \$\begingroup\$ You can get this down to somewhere around 109 bytes if you change cell B1's formula to =ROW(1:90)/9*PI() and the immediate window function to Sheet1.Shapes.AddChart2(,73,,,,360).Chart.SetSourceData[C1:D90] \$\endgroup\$ May 14, 2022 at 3:11
2
\$\begingroup\$

SageMath, 69 68 bytes

lambda a,t=var('t'):parametric_plot((a*t*cos(t),a*t*sin(t)),(t,0,9))

Try it online!

Saved a byte thanks to Seggan!!!

Current graph

Original graph using 42 instead of 9

Original graph (0,42)

\$\endgroup\$
3
  • 1
    \$\begingroup\$ You can replace the 42 with a 7, 8, or 9 to save 1 byte, although the graph wont be as big \$\endgroup\$
    – Seggan
    May 13, 2022 at 16:09
  • 1
    \$\begingroup\$ @Seggan But it looks so cool! :D \$\endgroup\$
    – Noodle9
    May 13, 2022 at 16:10
  • 1
    \$\begingroup\$ @Seggan But a golf is a golf - thanks! :D \$\endgroup\$
    – Noodle9
    May 13, 2022 at 16:17
2
\$\begingroup\$

SVG(HTML5) + JavaScript (ES6), 77 76 + 96 = 172 bytes

f=a=>s.setAttribute("points",[...Array(9e3)].map((_,i)=>[Math.sin(i/=100)*i*a,Math.cos(i)*i*a]))
;f(.1)
<input value=.1 oninput=f(+value)><br>
<svg viewBox=-4,-4,8,8><polyline id=s fill=none stroke=red stroke-width=.05>

Edit: Saved 1 byte thanks to @Kaiido.

\$\endgroup\$
2
  • \$\begingroup\$ You can omit the leading 0 in stroke-width. And I didn't check if it's part of your count but you can also remove this. in f(this.value) \$\endgroup\$
    – Kaiido
    May 15, 2022 at 12:22
  • \$\begingroup\$ @Kaiido There's a story behind that 0 - I was fiddling around trying to get something to work, but my problem was that I had a /, so nothing was working. Later I figured that I could remove the /, but forgot to remove the 0. Thanks for reminding me. \$\endgroup\$
    – Neil
    May 15, 2022 at 13:41
2
\$\begingroup\$

R, 42 bytes*

function(a,x=0:6e3/1e3)plot(a*x*pi*1i^x/2)

Try it at rdrr.io

Calculates the the points of the spiral as the real and imaginary parts of complex numbers, which is conveniently displayed directly as points on the complex plane by the R plot function.

*The *pi.../2 bit here is to scale the image so that the angle is in radians and achieve a distance between arms of exactly 2*pi. If we use an alternative unit of angular measurement, such as quadrants, we could drop this for 37 bytes: function(a,x=0:6e3/1e3)plot(a*x*1i^x).

Note also that the choice of 1e3 plotted points per quadrant was chosen to allow direct competition with pajonk's R answer; however, 99 plotted points per quadrant also gives a satisfactory output (the points overlap) and saves another byte: function(a,x=0:999/99)plot(a*x*1i^x).


R + pracma library, 39 bytes

function(a)pracma::polar(r<-0:99/9,a*r)

Try it at rdrr.io

Using a dedicated polar function doesn't save much, if anything at all.

\$\endgroup\$
1
\$\begingroup\$

Applesoft BASIC, 73 bytes

0GR
1COLOR=7
2INPUTR
3I=0
4PLOTCOS(I)*I*R+20,SIN(I)*I*R+20
5I=I+.1
6GOTO4

enter image description here

\$\endgroup\$
1
\$\begingroup\$

Clojure, 344 bytes

(defn s[a](doto(JFrame."")(.setPreferredSize(Dimension. 500 500))(.add(doto(proxy[JPanel][](paintComponent[g](.drawPolyline g (into-array Integer/TYPE(map #(+ 250(* a(/ % 20)(Math/cos(Math/toRadians %))))(range 3600)))(into-array Integer/TYPE(map #(- 250(* a(/ % 20)(Math/sin(Math/toRadians %))))(range 3600)))3600))))).pack(.setVisible true)))

Output for (s 1):

Spiral

\$\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.