[Question]
  [
The purpose of this challenge is to graphically depict a walk on the plane, where the direction of each step \$k\$ is determined by the primality of \$k\$ and the parity of its binary expansion. Specifically,
* **Initial** direction is fixed, say North.
* All steps have the same **length**.
* The **direction** of step \$k\$ can be North, West, South or East, and is determined as follows:
	+ If \$k\$ is not prime, the direction does not change.
	+ If \$k\$ is prime and the binary expansion of \$k\$ has an even number of ones, turn right.
	+ If \$k\$ is prime and the binary expansion of \$k\$ has an odd number of ones, turn left.
As a **worked example**, assume that the initial direction is North. The first steps are:
* \$k=1\$ is not prime. So we move one step in the current direction, which is North.
* \$k=2\$ is prime, and its binary expansion, `10`, has and odd number of ones. So we turn left, and are now facing West. We move one step in that direction.
* \$k=3\$ is prime, and its binary expansion, `11`, has and even number of ones. So we turn right, and are now facing North. We move one step in that direction.
* \$k=4\$ is not prime. So we move one step in the current direction, which is North.
# The challenge
**Input**: positive integer \$N\$.
**Output**: plot of the \$N\$-step walk as defined above.
# Additional rules
* The **initial direction** can be freely chosen (not necessarily North), but should be the same for all \$N\$.
* The **turning rule** can be the opposite to that described above, that is, turn right for odd parity and left for even; but it has to be the same for all \$N\$.
* The output has to be a **graphical depiction** of the walk. For instance:
	+ The walk can be drawn with line segments.
	+ The visited points can be shown with a marker, such as a dot; with or without connecting line segments.
	+ A two-colour raster image can be provided, with one colour corresponding to visited points and another for non-visited.
* The scales of the horizontal and vertical axes need not be the same. Also axis labels and similar elements are optional. As long as the walk can be clearly seen, the plot is valid.
* Note that some points are visited more than once. The plot is not sensitive to this. For instance, if line segments are shown in the plot, each unit segment is displayed the same no matter how many times it has been traversed.
* The code should work for any `N` given unlimited resources. It is acceptable if in practice it fails for large `N` due to time, memory or data-type limitations.
* Input and output are flexible as usual. In particular, any of the [standard means](https://codegolf.meta.stackexchange.com/questions/9093/default-acceptable-image-i-o-methods-for-image-related-challenges) for outputting images can be used.
* The shortest code in bytes wins.
# Test cases
The following plots use North as initial direction; even parity turns right; and the walk is depicted with line segments.
`N = 7`:
[![enter image description here](https://i.stack.imgur.com/3q92s.png)](https://i.stack.imgur.com/3q92s.png)
`N = 3000`:
[![enter image description here](https://i.stack.imgur.com/PTVYA.png)](https://i.stack.imgur.com/PTVYA.png)
`N = 20000`:
[![enter image description here](https://i.stack.imgur.com/ZKW3D.png)](https://i.stack.imgur.com/ZKW3D.png)
`N = 159000`:
[![enter image description here](https://i.stack.imgur.com/7lk1X.png)](https://i.stack.imgur.com/7lk1X.png)
`N = 1200000`:
[![enter image description here](https://i.stack.imgur.com/3jBBd.png)](https://i.stack.imgur.com/3jBBd.png)
`N = 11000000`:
[![enter image description here](https://i.stack.imgur.com/EdpKe.png)](https://i.stack.imgur.com/EdpKe.png)
  
[Answer]
# [MATL](https://github.com/lmendo/MATL), ~~25~~ ~~24~~ 21 bytes
```
Q:qJyZpbB!sEq*^YpYsXG
```
[Try it at MATL online](https://matl.io/?code=Q%3AqtZpwB%21soEqJ%2aq%2aQYpYsXG&inputs=7&version=20.11.0 "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\$:
[![enter image description here](https://i.stack.imgur.com/wR0R1.png)](https://i.stack.imgur.com/wR0R1.png)
[Answer]
# [Sledgehammer 0.4](https://github.com/tkwa/Sledgehammer), ~~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`](https://reference.wolfram.com/language/ref/AnglePath.html) and `ListPlot` do exactly what we need:
```
ListPlot[AnglePath[Array[%, #]]]&
```
In the interactive app, output is a rescalable vector Graphics object.
[![enter image description here](https://i.stack.imgur.com/BHmUv.png)](https://i.stack.imgur.com/BHmUv.png)
[Answer]
# [C (gcc)](https://gcc.gnu.org/), 179 bytes
```
o;i;d;k;h;f(n,p)char*p;{h=2*n+1;memset(p,0,h*h);p+=h--*n+n;*p=1;for(d=k=0;k++<n;){for(i=1;k%++i%k;);for(o=k;o/2;o=o/2^o&1);i==k?d+=o*2+3:0;p+=(d%2*h+1)*((d&2)-1);*p=1;}return++h;}
```
[Try it online!](https://tio.run/##VZBNboMwEIXX5RSjRAn@CS3QdJOJm4NEqURtiC3ARkDaRZSrl9qkatWNPX7v8zzNyOQs5TQ5NKiwRo0VsZuOSl30rMOrFjmzPMO2bIdyJN0m3WimKXZc6CTxlkXWiQwr1xMlapFizfneIr0GxXinXnFuVjXSmXGiRveUoxP@fHPrjKIRoj4oLhzL@fMuDa2JWuVM84wyQtQ6p4nH5phbX46X3nKu8TYtjZXNRZWwH0Zl3KN@jf5JjXkPWmTsCG1hLAlF0Z/lBsJ4wJh/fFC4Rg/BsSCgGJ0hQT1mJ4rRw50zbXEuvdsWTeMk2TLrB9@GvQQm/B2MCkDYHcx0MPy8MGcab6Xor/0M@orzOfYPkXdE/iIyIF3vvYosVnLx0/dogN3TOMgTHCBexrCDGGKK4Bt2l3Egi0WIv0W3aJpe0i9ZNcV5mJLPbw "C (gcc) – Try It Online")
A function. First argument is N, second argument is an allocated buffer of size at least \$4 n^2 + 4 n + 1\$ bytes. A square image is written to this buffer, its side length is returned. In the image, `0` is a white pixel, `1` is a black pixel.
# [C (gcc)](https://gcc.gnu.org/), 219 bytes
```
o;i;d;k;h;f(n,p)char*p;{h=2*n+1;p+=sprintf(p,"P1 %d %d ",h,h);memset(p,48,h*h);k=h--*n+n;*(p+2*k+1)=0;p+=k;*p=49;for(d=k=0;k++<n;){for(i=1;k%++i%k;);for(o=k;o/2;o=o/2^o&1);i==k?d+=o*2+3:0;p+=(d%2*h+1)*((d&2)-1);*p=49;}}
```
[Try it online!](https://tio.run/##XZDbTsMwDIav16eIhjrl0MJaKnHwAq/APQKpJG0TpU2itoOLaa9OSToJIaQksj/7t2OLvBNiWRxokGBAQYtt5olQ9Ug9nBQvqWUFeMYnP2o7t9hn25cCpTKebaYyRWBohqmZQ6S6zxQNwHCV50FogWLPSmpYQfg@VjFAPa8eoHUjltwEaBg7WCCnSDQvwKSM6dQAWXNcULibEhwP77vbFQQ05@ZZMu5oyW4f16pYpiVVoQnFWO5Kkoe0S5/zebnSVvRH2aDDNEvtrtVT8heFqbr/TPb6I7IkTIyGWlscjXrsRIbiahClwfkk6JRsYsQijurZaRzpa/FGINlc8vRQd02IDnXfO4ErasNaqvWG1n1jfyXsLqri@tEqWj1/nCe8uhkK33LHOeDzshT7/bdo@7qblvzrBw "C (gcc) – Try It Online")
A function. First argument is N, second argument is an allocated buffer of size at least \$4 n^2 + 4 n + 2 \times \lfloor log\_{10}(2n+1)\rfloor + 9\$ bytes. A square image in PBM format is written to the buffer.
Cropped output for 20000:
[![cropped output for 20000](https://i.stack.imgur.com/O8jRm.jpg)](https://i.stack.imgur.com/O8jRm.jpg)
Both versions start with west and turn right on odd, left on even.
I tried the larger testcases with neither of them, as the output with 20000 was ~1.5 GB, and 150000 would have been ~90GB. This is all stored in memory while the program executes.
Explanation of the upper one:
```
o;         /* Temporary variable for calculating parity */
i;         /* Temporary variable for primality test */
d;         /* d % 4 = direction */
k;         /* Step */
h;         /* height/width of image */
f(n,p)char*p;{ /* Function taking int and char pointer */
  h=2*n+1;     /* Image sidelength = 2 * N + 1, so N in each direction */
  memset(p,0,h*h); /* Reset buffer */
  p+=h--*n+n;  /* Position p at image center; decrement h */
  *p=1;        /* Put a dot at center */
  for(d=k=0;   /* Set direction and step to 0 */
    k++<n;){   /* Loop over [1..N] */
    for(i=1;k%++i%k;); /* Primality test */
    for(o=k;o/2;o=o/2^o&1); /* Parity test */
    i==k?d+=o*2+3:0; /* Change direction if necessary */
    p+=(d%2*h+1)*((d&2)-1); /* Move according to direction */
    *p=1; /* Set pixel to black */
  }
  return++h; /* Add 1 back to h and return */
}
```
[Answer]
# [Wolfram Language (Mathematica)](https://www.wolfram.com/wolframscript/), ~~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`](https://codegolf.stackexchange.com/a/187344/87058)...
-13 bytes: ...and [`ThueMorse`](https://reference.wolfram.com/language/ref/ThueMorse.html)!
usage example:
```
%[20000]
```
[![enter image description here](https://i.stack.imgur.com/U0EOe.png)](https://i.stack.imgur.com/U0EOe.png)
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's `Total[#~IntegerDigits~2]` (which is the same, modulo 2).
* [`Array[Pi/2*%,#]`](https://reference.wolfram.com/language/ref/Array.html) 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[%]`](https://reference.wolfram.com/language/ref/AnglePath.html) converts this list of direction-change angles into a path. This instruction replaces the previous solution's double-use of `Accumulate`.
* [`ListPlot[%]`](https://reference.wolfram.com/language/ref/ListPlot.html) converts the list of positions into a XY dot plot. If a line is preferred, use [`ListLinePlot`](https://reference.wolfram.com/language/ref/ListLinePlot.html) instead. These plotting functions have lots of options to make the plots look better.
[Answer]
# MATL, ~~31~~ ~~30~~ ~~28~~ 26 bytes
```
J4:^0i:Zpl_G:B!s^*hYs)YsXG
```
*3 Bytes saved thanks to @LuisMendo*
*2 Bytes saved thanks to @Sanchises*
Try it at [MATL Online](https://matl.suever.net/?code=J4%3A%5E0i%3AZpl_G%3AB%21s%5E%2ahYs%29YsXG&inputs=100&version=20.11.0)
**Explanation**
This solution uses complex numbers to represent the X and Y components of the 2D plane
```
J      % Push the literal complex number 0 + 1j to the stack
4:     % Create the array [1, 2, 3, 4]
^      % Raise 0 + 1j to each power in the array, [1, 2, 3, 4]
```
At this point, we have four points (`(0, 1), (-1, 0), (0, -1), (1, 0)`) in an array represented by complex numbers. These are the four cardinal directions. Now we want to use these to "walk".
Essentially the way that this works is that we start heading in the zero'th direction (the 0'th element of the array which is `(-1, 0)`). For each step, we need to determine the change in this heading. We will use integers to track this change. If we want to turn "right", we increment this integer by 1 (referencing the *next* element in the 4-point array) and if we want to go "left", we decrement this integer by 1 (referencing the *previous* element in the 4-point array). If we want to continue on our path, we keep the integer value constant (referencing the *same* element in the 4-point array).
This part of the code creates an array of all of those `0`, `-1`, and `1` values.
```
0      % Push a literal 0 to the stack (the starting point)
i      % Explicitly grab the input (N)
:      % Create an array from 1...N
Zp     % Determine if each element is a prime (1) or not (0)
l_     % Push the literal -1 to the stack
G      % Explicitly grab the input again (N)
:      % Create an array from 1...N
B      % Convert to binary representation (each row is the binary representation of
       % each element in the vector)
!      % Transpose
s      % Sum down the columns to count number of 1's
^      % Raise the -1 to each element. For odd number of 1's in the
       % binary expansion this yields -1, and even yields 1
*      % Multiply this -1 or 1 by the result of the prime check (element-wise). 
       % For non-primes this yields a 0, for primes with an even number of 1's in 
       % the binary representation this is a 1, and for primes 
       % with an odd number of 1's in
h      % Horizontally concatenate with the initial 0
```
Now we have an array of the differences between successive integers so we can compute the cumulative sum of those up to get the indices which we can then use to lookup the direction at each step in the original 4-element array.
Conveniently, MATL has wrap-around indexing such that index `5` wraps around to the beginning of a 4-element array. We can use this to our advantage so that we can increment and decrement this integer without worrying about the fact that the reference direction array is only 4 elements.
```
Ys     % Compute the cumulative sum
)      % Use this to modularly index into the original array of four points
```
Now we have an array of directions of steps takes, so we can compute the cumulative sum of these directions to trace out the path that was taken.
```
Ys     % Compute the cumulative sum
XG     % Plot as a 2D plot
```
[Answer]
# [Perl 6](http://perl6.org/), ~~213~~ 182 bytes
~~{my @p=[\+] [\\*]({{.is-prime??.base(2).comb(~1)%2??i!!-i!!1+0i}(++$)}...\*)[^$\_];{"<svg viewBox='{.min xx 2,.elems xx 2}'>>.&{"L{.re} {.im}"}}' fill='none' stroke='black'/>"}(minmax |@p».reals)}~~
```
{{"<svg viewBox='{{.min,.min,+$_,+$_}(.minmax)}'><path d='{"L"X~$_}' fill='none' stroke='red'/></svg>"}(([\+] [\*]({-{.is-prime*.base(2).comb(~1)R**-1||i}(++$)i}...*)[^$_])».reals)}
```
[Try it online!](https://tio.run/##HYy9DoIwAIRfpSHE/iBFHJyAwdnJyQSRVCnaSIG0BCG1vpibL4bocJd8uS/XclVtJjmCRQniyRgn0v0V9II/ts0QQ2OoFPXyX56b/2LRjyQbsIVJ1LLuBopZdHbO4TWvEJSiqmJYNzWHQHequfMYKl7AIImC@TxxLELp0ctAeiQZMr6hQvutEpITemaaozWml0ae0SvEe0L88PkUFnmei4WllBKcntw8w583VZxVGttJsxGUKFzh6Qs "Perl 6 – Try It Online")
(Really managed to pare this one down!)
This function outputs in SVG format.
* `{ -{ .is-prime * .base(2).comb(~1) R** -1 || i }(++$)i } ... *` is an infinite sequence of direction changes for each step, in the form of complex numbers, where `1` means "continue in the same direction," `i` means "turn left," and `-i` means "turn right."
* `[^$_]` limits that sequence to the number of steps provided as the function's argument.
* `[\*]` scans that sequence with (complex) multiplication, turning the list of relative direction changes into a list of absolute directions.
* `[\+]` scans *that* sequence with (complex) addition, producing a list of the visited coordinates.
* `».reals` converts that list of complex numbers into two-element lists of its real and imaginary parts.
The SVG image is just one single `path` element.
Output (converted to PNG) for N = 20000:
[![path for N = 20000](https://i.stack.imgur.com/B8n94.png)](https://i.stack.imgur.com/B8n94.png)
[Answer]
## C, 321 bytes
```
a,b,A,B,k,p,e,i,t,r;g(n,c,d,x,y,X,Y){x=y=Y=r=0;X=1;for(k=0;k++<=n;){r|=x==c&y==d;a=x<a?x:a;A=x>A?x:A;b=y<b?y:b;B=y>B?y:B;for(p=1,i=k;--i;p=p*i*i%k);for(e=1,i=k;i;e=-e)i&=i-1;if(p)t=X,X=-e*Y,Y=e*t;x+=X;y+=Y;}}f(n,x,y){A=a=B=b=0;g(n);printf("P1%d %d ",A-a+1,B-b+1);for(y=b;y<=B;++y)for(x=a;x<=A;++x)g(n,x,y),putchar(48+r);}
```
[Try it online!](https://tio.run/##LY/RaoNAFER/RQIJu@5dUOhDyXUS1i/ooz6uRpNFakUs7GL9drtNA/dhmIG5Z1p9b9t9t9SQoZIGmqgjRwvNfBcjtXQjT4EqquXqEVBjRsYVcu6/ZjFEPShVYGS5zj/wQHsKwI0tfGGv/mzZwF9MVIYbhKK5hnPDJcKljKp8tkzIyWFgrR1PmFKXuuMgn1H3ihx30J10Jzids@vFJBdUVEUzralGly7sFSoOCjVvWx/ZI7dcDSxKNJEzzpE8zW5cenH4yI@3JN6BjLYqp1I3Kv9/GdBwKFCyUkH@GR6WfQETDS/vr2Kavpf2YWfx9q5mydv@ad0oZLImvcizLJOcbPsv)
I started working on this before the other C answer was posted, but I figured I might as well post mine as well anyway. This one is a lot longer, but it also crops the output image to the dimensions of the result automatically.
Function is called as `f(n)`, and output is to stdout in netpbm format.
Example output for n=1000:
[![](https://i.stack.imgur.com/j494m.png)](https://i.stack.imgur.com/j494m.png)
```
a,b,A,B,          // used to store x range [a,A] and y range [b,B]
k,p,e,i,t,        // temp variables used in g
r;g(n,c,d,        // takes n + coordinates, sets r to whether (c,d) is visited
x,y,X,Y){         // temp variables - position (x,y) and velocity (X,Y)
x=y=Y=r=0;X=1;    // initialization
for(k=0;k++<=n;){ // loops k over the step number
r|=x==c&y==d;     // set r to 1 if current coordinate is the requested one
a=x<a?x:a;A=x>A?x:A;b=y<b?y:b;B=y>B?y:B;    // update bounds
for(p=1,i=k;--i;p=p*i*i%k);                 // prime test
for(e=1,i=k;i;e=-e)i&=i-1;                  // parity test
if(p)t=X,X=-e*Y,Y=e*t;                      // if prime, turn accordingly
x+=X;y+=Y;}}      // move position in direction of velocity
f(n,x,y){         // main function; x and y are temp variables
A=a=B=b=0;g(n);   // obtain accurate bounds
printf("P1 %d %d\n",A-a+1,B-b+1);           // output netpbm header
for(y=b;y<=B;++y)for(x=a;x<=A;++x)          // loop through all coordinates
g(n,x,y),putchar(48+r);}                    // output 1 if visited, 0 otherwise
```
The prime test is essentially the one used in [Lynn's answer to a different challenge](https://codegolf.stackexchange.com/a/57676/3808), which relies on [Wilson's theorem](https://en.wikipedia.org/wiki/Wilson%27s_theorem).
The parity test uses an adaptation of [Kernighan's bit-counting method](https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan).
Since the prime test is very slow, and the algorithm re-runs the entire path generation function for each pixel drawn, any input much higher than 1000 times out on TIO.
[Answer]
## LOGO, ~~177~~ 171 bytes
```
to d:c
if :c%2[rt 180
make"c:c-1]if:c<1[stop]d:c/2
end
to p
if:c>1[make"f 2
repeat:c-2[if:c%:f<1[stop]make"f:f+1]rt 90
d:c]end
to g:n
make"c 1
repeat:n[p
fw 2
make"c:c+1]end
```
To use, do something like [this](http://logo.twentygototen.org/biBItc1a):
```
reset
pu
fw 100
pd
g 3000
```
Sorry, but I wasn't able to capture sample output. Explanation:
```
to d:c
if :c%2[rt 180
make"c:c-1]if:c<1[stop]d:c/2
end
```
This is a recursive procedure which rotates 180° for every set bit in its parameter, which effectively computes the parity of its binary expansion.
```
to p
if:c>1[make"f 2
repeat:c-2[if:c%:f<1[stop]make"f:f+1]rt 90
d:c]end
```
This is a very basic primality test. After special-casing 1, the procedure early returns if a factor is found. If however the current value is found to be prime, it turns right, and then uses the above procedure to change that into a left turn as appropriate.
```
to g:n
make"c 1
repeat:n[p
fw 2
make"c:c+1]end
```
This is just a simple loop to test all the numbers up to `n` for primality and to move two pixels after each one.
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 41 bytes
```
B§ḂḤ’×ıµ1Ẓ?€×\ÄŻÆiZ_Ṃ$€Z‘ḞŒṬµẈḢ⁾P1,;Lṭ@FK
```
[Try it online!](https://tio.run/##AV0Aov9qZWxsef//QsKn4biC4bik4oCZw5fEscK1MeG6kj/igqzDl1zDhMW7w4ZpWl/huYIk4oKsWuKAmOG4nsWS4bmswrXhuojhuKLigb5QMSw7TOG5rUBGS////zMwMDA "Jelly – Try It Online")
Full program that takes a single argument \$N\$ and outputs a 1-bit PBM to STDOUT. Takes some inspiration from [@Sanchises MATL answer](https://codegolf.stackexchange.com/a/187330/42248). Starts off going South and turns left on odd bit parity. 
Sample output for \$N=3000\$:
[![Output for N=3000](https://i.stack.imgur.com/gz86b.jpg)](https://i.stack.imgur.com/gz86b.jpg)
If ASCII Art were permissible, [here’s an alternative 29-byte variant](https://tio.run/##AUcAuP9qZWxsef//QsKn4biC4bik4oCZw5fEscK1MeG6kj/igqzDl1zDhMW7w4ZpWl/huYIk4oKsWuKAmOG4nsWS4bmsWf///zMwMA) which yields (for \$N=300\$):
```
0000000000000000000000111110000000000
0000000000000000000000100010000000000
0000001110000000000000100010000000000
0000001010000000000000100010000000000
0000001010000000000000100010000000000
0000001010000000000000100010000000000
0000001010000000111111111010000000000
0000001010000000100000101010000000000
0000001111111110100000101010000000000
0000000000100010100000101010000000000
0000000000111111100000101010001111111
0000000000000010000000101010001000001
0000000000000011100010101010001000001
0000000000000000100010101010001000001
0000111111100000100011111111111111111
0100100000100000100010001010001000001
0110100000111111100011111111111000111
0010100000000000000010101010000000101
1111100000000000000010101110000000101
1010000000000000000010100000000000101
1010000000000000000011111111111011101
1010000000000000000000100000001010101
1110000000000000000000111111101111101
0000000000000000000000000000100010101
0000000000000000000000000000100010101
0000000000000000000000000000100010101
0000000000000000000000000000111111111
0000000000000000000000000000000010100
0000000000000000000000000000000010100
0000000000000000000000000000000010100
0000000000000000000000000000000011100
```
[Answer]
# JavaScript - ~~675~~ ~~668~~ ~~660~~ ~~632~~ ~~556~~ 534 Bytes
First time here on CodeGolf, initially started with ~1500 Bytes Code. Golfed it to ~~less than half~~ ~~nearly~~ more than a third of it. Feel free to continue golfing. Bytes Counted with: [this tool](https://mothereff.in/byte-counter)
Principle:  
Draws into fixed size canvas with N and variable stroke length as input.
### Edits:
-07 Bytes - remove of missed if   
-08 Bytes - change switch to if/else   
-28 Bytes - change to tenary if/else   
-76 Bytes - shorter prime test (runtime / 3)  
-22 Bytes - use [this](https://codegolf.stackexchange.com/a/91309/74284) prime function (runtime \* 4)
### Golfed Code:
```
function f(e,r){for(var t=0,n=0,i=950,f=450,o=document.getElementById("d").getContext("2d"),a=1;a<=e;a++){n=iP(a)?iO(a)?1:2:0;var u=i,c=f;t==0?(t=0==n?(c=f-r,0):1==n?(u=i-r,1):(u=i+r,3)):t==1?(t=0==n?(u=i-r,1):1==n?(c=f+r,2):(c=f-r,0)):t==2?(t=0==n?(c=f+r,2):1==n?(u=i+r,3):(u=i-r,1)):(t=0==n?(u=i+r,3):1==n?(c=f-r,0):(c=f+r,2));o.beginPath(),o.moveTo(i,f),o.lineTo(u,c),o.stroke(),i=u,f=c}}function iP(h){for(i=n=h;n%--i;);return(1==i)}function iO(e){for(var r=(e>>>0).toString(2),t=0,n=0;n<r.length;n++)"1"==r[n]&&t++;return t%2!=0}
```
### Ungolfed code with whitespaces:
```
function f(e,r){
    for(var t=0,n=0,i=950,f=450,o=document.getElementById("d").getContext("2d"),a=1;a<=e;a++){
        // prime and odd/even check
        n=iP(a)?iO(a)?1:2:0;
        var u=i,c=f;
        t==0?(t=0==n?(c=f-r,0):1==n?(u=i-r,1):(u=i+r,3)):t==1?(t=0==n?(u=i-r,1):1==n?(c=f+r,2):(c=f-r,0)):t==2?(t=0==n?(c=f+r,2):1==n?(u=i+r,3):(u=i-r,1)):(t=0==n?(u=i+r,3):1==n?(c=f-r,0):(c=f+r,2));
        o.beginPath(),o.moveTo(i,f),o.lineTo(u,c),o.stroke(),
        i=u,f=c // renew old cords
    }
}
// check prime
function iP(h){
    for(i=n=h;n%--i;);
    return(1==i)
}
// check binary expression even/odd
function iO(e){
    for(var r=(e>>>0).toString(2),t=0,n=0;n<r.length;n++)
        "1"==r[n]&&t++;
    return t%2!=0
}
```
### Examples:
> 
> N = 7 - Length = 60
>  
> 
> 
> ```
> f(7, 60);
> function f(e,r){for(var t=0,n=0,i=950,f=450,o=document.getElementById("d").getContext("2d"),a=1;a<=e;a++){n=iP(a)?iO(a)?1:2:0;var u=i,c=f;t==0?(t=0==n?(c=f-r,0):1==n?(u=i-r,1):(u=i+r,3)):t==1?(t=0==n?(u=i-r,1):1==n?(c=f+r,2):(c=f-r,0)):t==2?(t=0==n?(c=f+r,2):1==n?(u=i+r,3):(u=i-r,1)):(t=0==n?(u=i+r,3):1==n?(c=f-r,0):(c=f+r,2));o.beginPath(),o.moveTo(i,f),o.lineTo(u,c),o.stroke(),i=u,f=c}}function iP(h){for(i=n=h;n%--i;);return(1==i)}function iO(e){for(var r=(e>>>0).toString(2),t=0,n=0;n<r.length;n++)"1"==r[n]&&t++;return t%2!=0}
> ```
> 
> 
> ```
> <canvas id="d" width="1900" height="900"/> 
> ```
> 
> 
> 
> 
> 
> 
> N = 3000 - Length = 4
>  
> 
> 
> ```
> f(3000, 4);
> function f(e,r){for(var t=0,n=0,i=950,f=450,o=document.getElementById("d").getContext("2d"),a=1;a<=e;a++){n=iP(a)?iO(a)?1:2:0;var u=i,c=f;t==0?(t=0==n?(c=f-r,0):1==n?(u=i-r,1):(u=i+r,3)):t==1?(t=0==n?(u=i-r,1):1==n?(c=f+r,2):(c=f-r,0)):t==2?(t=0==n?(c=f+r,2):1==n?(u=i+r,3):(u=i-r,1)):(t=0==n?(u=i+r,3):1==n?(c=f-r,0):(c=f+r,2));o.beginPath(),o.moveTo(i,f),o.lineTo(u,c),o.stroke(),i=u,f=c}}function iP(h){for(i=n=h;n%--i;);return(1==i)}function iO(e){for(var r=(e>>>0).toString(2),t=0,n=0;n<r.length;n++)"1"==r[n]&&t++;return t%2!=0}
> ```
> 
> 
> ```
> <canvas id="d" width="1900" height="900"/> 
> ```
> 
> 
> 
> 
> 
> 
> N = 20000 - Length = 2
>  
> 
> 
> ```
> f(20000, 2);
> function f(e,r){for(var t=0,n=0,i=950,f=450,o=document.getElementById("d").getContext("2d"),a=1;a<=e;a++){n=iP(a)?iO(a)?1:2:0;var u=i,c=f;t==0?(t=0==n?(c=f-r,0):1==n?(u=i-r,1):(u=i+r,3)):t==1?(t=0==n?(u=i-r,1):1==n?(c=f+r,2):(c=f-r,0)):t==2?(t=0==n?(c=f+r,2):1==n?(u=i+r,3):(u=i-r,1)):(t=0==n?(u=i+r,3):1==n?(c=f-r,0):(c=f+r,2));o.beginPath(),o.moveTo(i,f),o.lineTo(u,c),o.stroke(),i=u,f=c}}function iP(h){for(i=n=h;n%--i;);return(1==i)}function iO(e){for(var r=(e>>>0).toString(2),t=0,n=0;n<r.length;n++)"1"==r[n]&&t++;return t%2!=0}
> ```
> 
> 
> ```
> <canvas id="d" width="1900" height="900"/> 
> ```
> 
> 
> 
> 
> 
> 
> N = 159000 - Length = 1
>  
> 
> 
> ```
> f(159000, 1);
> function f(e,r){for(var t=0,n=0,i=950,f=450,o=document.getElementById("d").getContext("2d"),a=1;a<=e;a++){n=iP(a)?iO(a)?1:2:0;var u=i,c=f;t==0?(t=0==n?(c=f-r,0):1==n?(u=i-r,1):(u=i+r,3)):t==1?(t=0==n?(u=i-r,1):1==n?(c=f+r,2):(c=f-r,0)):t==2?(t=0==n?(c=f+r,2):1==n?(u=i+r,3):(u=i-r,1)):(t=0==n?(u=i+r,3):1==n?(c=f-r,0):(c=f+r,2));o.beginPath(),o.moveTo(i,f),o.lineTo(u,c),o.stroke(),i=u,f=c}}function iP(h){for(i=n=h;n%--i;);return(1==i)}function iO(e){for(var r=(e>>>0).toString(2),t=0,n=0;n<r.length;n++)"1"==r[n]&&t++;return t%2!=0}
> ```
> 
> 
> ```
> <canvas id="d" width="1900" height="900"/> 
> ```
> 
> 
> 
> 
> 
> 
> 
[Answer]
# [Red](http://www.red-lang.org), ~~515~~ ~~480~~ 471 bytes
-1 byte thanks to Kevin Cruijssen! 
```
func[n][a: 270 x: t: u: v: w: 0 y: 1
b: copy[line 0x0 0x1]repeat i n - 1[p: on
j: i + 1 repeat k i / 2[if j%(k + 1)= 0[p: off]]if p[s: 0
until[if j% 2 = 1[s: s + 1](j: j / 2)< 1]a: a + pick[-90 90]s% 2 + 1]append b 'line 
append b as-pair x y x: x + cosine a y: y - sine a append b as-pair x y t: min x t
u: max x u v: min y v w: max y w]c: 500 /(max u - t w - v)view[base white 502x500
draw collect[foreach k b[keep either pair? k[as-pair k/1 - t * c k/2 - v * c][k]]]]]
```
A significant part of the code (~160 bytes) deals with normalizing the coordinates so that the graphics fits entirely in the canvas regardless of the size of the input. 
Initial direction: South. 
Here's the result for `n = 3000`
## [3000 iterations](https://i.stack.imgur.com/75ive.png)
`n = 20000`
[![20000](https://i.stack.imgur.com/oVMPT.png)](https://i.stack.imgur.com/oVMPT.png)
[Answer]
# Processing , 140+ bytes
```
void f(int N){for(int x,y,i,l,d,k=d=y=x=0;k++<N;d+=i<l?0:Integer.bitCount(k)%2*2-1,d&=3,point(x-=~-d%2,y+=(d-2)%2))for(i=1,l=k;0<l%++i%l;);}
```
Might not fulfill clearly seen
[![walk](https://i.stack.imgur.com/hsnvs.png)](https://i.stack.imgur.com/hsnvs.png)
]