Prime parity peregrination
MATL, 25 24 21 bytes
Q:qJyZpbB!sEq*^YpYsXG
Try it at MATL online
Thanks @LuisMendo for a nice golfing session in chat that ultimately led to this 21 byte version, by suggesting Eq*^
Explanation
Q:q % Push 0:n
J % Push 1i for later use.
y % Duplicate 0:n from below
Zp % Vector result of isprime()
b % Bubble 0:n from bottom of stack
B!s % Sum of bits in binary representation
Eq % Double minus one to get an odd number
* % Multiply by isprime result to get either zero or aforementioned odd number
^ % Exponentiate 1i by an odd number or zero to get -i, 1 or i (corresponding to left turn, straight ahead, right turn).
Yp % Cumulative product to get a vector of directions
Ys % Cumulative sum to get vector of positions
XG % Plot
Example for \$k=12345\$:
Sledgehammer 0.4, 22 20 bytes
⢂⡐⠥⡄⠡⢒⣩⣀⣼⡝⢄⡎⣛⠅⡉⣱⡆⢀⡠⣽
Decompresses into this Wolfram Language function:
ListPlot[AnglePath[Array[If[PrimeQ@#, ArcSin[(-1)^ThueMorse@#], 0] &, #]]]
Ungolfed
First we define a function that returns the angle to turn at each step:
If[PrimeQ[#],
ArcSin[(-1)^ThueMorse@#],
0
]&
ThueMorse
is the parity of the sum of binary digits. We use -1^(...)
rather than 2*...-1
for a slightly complicated reason: Wolfram Language automatically converts arithmetic expressions in source to a canonical form, so expressions like 2/x
are stored as Times[2, Power[x, -1]]
. This makes the frequency of Power
very high, and thus compressing it very cheap.
(Multiplying by Boole@PrimeQ@
is slightly longer, and implicit Boole
casting of Booleans had not been implemented at the time of the challenge.)
From here, Mathematica's AnglePath
and ListPlot
do exactly what we need:
ListPlot[AnglePath[Array[%, #]]]&
In the interactive app, output is a rescalable vector Graphics object.
Wolfram Language (Mathematica), 98 96 91 77 76 63 bytes
ListPlot@AnglePath@Array[Pi/2If[PrimeQ@#,2ThueMorse@#-1,0]&,#]&
-14 bytes: Thanks to @lirtosiast for showing me how to use AnglePath
...
-13 bytes: ...and ThueMorse
!
usage example:
%[20000]
Step-by-step explanation:
If[PrimeQ@#, 2 ThueMorse@# - 1, 0] &
is a function that takes the step index and returns 0 for non-primes, -1 for even-binary primes, and +1 for odd-binary primes.ThueMorse@#
replaces the previous solution'sTotal[#~IntegerDigits~2]
(which is the same, modulo 2).Array[Pi/2*%,#]
makes a list of this function with the index going from 1 to the function argument (20000 in the example), and multiplies every element by π/2 to make it into a direction-change angle (radians). We now have 0 for non-primes, -π/2 for even-binary primes, and +π/2 for odd-binary primes.AnglePath[%]
converts this list of direction-change angles into a path. This instruction replaces the previous solution's double-use ofAccumulate
.ListPlot[%]
converts the list of positions into a XY dot plot. If a line is preferred, useListLinePlot
instead. These plotting functions have lots of options to make the plots look better.