Peregrinación de primera paridad


44

El propósito de este desafío es representar gráficamente una caminata en el plano, donde la dirección de cada paso k está determinada por la primalidad de k y la paridad de su expansión binaria. Específicamente,

  • La dirección inicial es fija, digamos Norte.
  • Todos los pasos tienen la misma longitud .
  • La dirección del paso k puede ser Norte, Oeste, Sur u Este, y se determina de la siguiente manera:
    • Si k no es primo, la dirección no cambia.
    • Si k es primo y la expansión binaria de k tiene un número par, gire a la derecha.
    • Si k es primo y la expansión binaria de k tiene un número impar, gire a la izquierda.

Como ejemplo trabajado , suponga que la dirección inicial es Norte. Los primeros pasos son:

  • k=1 no es primo. Entonces nos movemos un paso en la dirección actual, que es Norte.
  • k=2 es primo, y su expansión binaria10, tiene un número impar de unidades. Entonces giramos a la izquierda y ahora estamos mirando hacia el oeste. Nos movemos un paso en esa dirección.
  • k=3 es primo, y su expansión binaria11, tiene e incluso un número de unos. Entonces giramos a la derecha y ahora estamos mirando al norte. Nos movemos un paso en esa dirección.
  • k=4 no es primo. Entonces nos movemos un paso en la dirección actual, que es Norte.

El reto

Entrada : entero positivo N .

Salida : diagrama de la caminata N -step como se definió anteriormente.

Reglas adicionales

  • La dirección inicial se puede elegir libremente (no necesariamente del Norte), pero debe ser el mismo para todos N .
  • La regla de giro puede ser la opuesta a la descrita anteriormente, es decir, girar a la derecha para paridad impar y a la izquierda para par; pero tiene que ser el mismo para todos los N .
  • La salida tiene que ser una representación gráfica de la caminata. Por ejemplo:
    • La caminata se puede dibujar con segmentos de línea.
    • Los puntos visitados se pueden mostrar con un marcador, como un punto; con o sin segmentos de línea de conexión.
    • Se puede proporcionar una imagen ráster de dos colores, con un color correspondiente a los puntos visitados y otro para los no visitados.
  • Las escalas de los ejes horizontal y vertical no necesitan ser las mismas. También las etiquetas de eje y elementos similares son opcionales. Mientras la caminata se pueda ver claramente, la trama es válida.
  • Tenga en cuenta que algunos puntos se visitan más de una vez. La trama no es sensible a esto. Por ejemplo, si los segmentos de línea se muestran en el gráfico, cada segmento de unidad se muestra igual sin importar cuántas veces se haya recorrido.
  • El código debería funcionar para cualquier Nrecurso ilimitado dado. Es aceptable si en la práctica falla por mucho Ntiempo debido a limitaciones de tiempo, memoria o tipo de datos.
  • La entrada y la salida son flexibles como de costumbre. En particular, se puede utilizar cualquiera de los medios estándar para generar imágenes.
  • El código más corto en bytes gana.

Casos de prueba

Las siguientes parcelas usan el norte como dirección inicial; incluso la paridad gira a la derecha; y la caminata se representa con segmentos de línea.

N = 7:

ingrese la descripción de la imagen aquí

N = 3000:

ingrese la descripción de la imagen aquí

N = 20000:

ingrese la descripción de la imagen aquí

N = 159000:

ingrese la descripción de la imagen aquí

N = 1200000:

ingrese la descripción de la imagen aquí

N = 11000000:

ingrese la descripción de la imagen aquí


1
¿Hay alguna razón que solo [graphical-output]esté permitida? ¿Alguna razón en particular para la salida ASCII no permitida, como mi respuesta Charcoal ahora eliminada?
Kevin Cruijssen

2
@Kevin Una vez me aconsejaron no mezclar ambos en el mismo desafío ... ¿Qué piensan los demás?
Luis Mendo

1
Bueno, puedo entender el razonamiento detrás de ese consejo, ya que la salida como imagen / gráfico versus arte ASCII es completamente diferente en algunos idiomas. Por otra parte, he visto salidas gráficas obteniendo un montón de votos a favor en los desafíos de arte ASCII y viceversa, así que supongo que no todos están de acuerdo. Personalmente, creo que realmente depende del desafío. En este caso, personalmente no veo ningún daño al permitir ambos en el mismo desafío, pero tal vez soy parcial debido a mi respuesta ahora eliminada. Así que haré la misma pregunta que tú: " ¿Qué piensan los demás? " @Arnauld Quizás deberías publicar tu conductor de taxi ASCII después de todo;)
Kevin Cruijssen

1
Sería interesante ver esta ejecución en varias secuencias OEIS (es cierto, algunas simplemente caminarían en línea recta o correrían en círculos, pero algunas podrían ser algo bastante).
Draco18s

16
En N = 11000000, parece estar aproximándose al mapa de Europa.
Trauma digital

Respuestas:


12

Sledgehammer 0.4 , 22 20 bytes

⢂⡐⠥⡄⠡⢒⣩⣀⣼⡝⢄⡎⣛⠅⡉⣱⡆⢀⡠⣽

Se descomprime en esta función Wolfram Language:

ListPlot[AnglePath[Array[If[PrimeQ@#, ArcSin[(-1)^ThueMorse@#], 0] &, #]]]

Sin golf

Primero definimos una función que devuelve el ángulo para girar en cada paso:

If[PrimeQ[#],
    ArcSin[(-1)^ThueMorse@#],
    0
]&

ThueMorsees la paridad de la suma de dígitos binarios. Usamos en -1^(...)lugar de 2*...-1por una razón un poco complicada: Wolfram Language convierte automáticamente las expresiones aritméticas en origen a una forma canónica, por lo que las expresiones como 2/xse almacenan como Times[2, Power[x, -1]]. Esto hace que la frecuencia sea Powermuy alta y, por lo tanto, comprimirla es muy barata.

(Multiplicar por Boole@PrimeQ@es un poco más largo, y el Boolelanzamiento implícito de booleanos no se había implementado en el momento del desafío).

Desde aquí, Mathematica's AnglePathy ListPlothacemos exactamente lo que necesitamos:

ListPlot[AnglePath[Array[%, #]]]&

En la aplicación interactiva, la salida es un objeto de gráficos vectoriales reescalable.

ingrese la descripción de la imagen aquí


¡Guay! Llegué a 77 bytes combinando nuestras soluciones. ¡Aclamaciones!
Roman

14

MATL , 25 24 21 bytes

Q:qJyZpbB!sEq*^YpYsXG

Pruébelo en MATL en línea

Gracias @LuisMendo por una buena sesión de golf en el chat que finalmente condujo a esta versión de 21 bytes, al sugerir Eq*^

Explicación

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

k=12345ingrese la descripción de la imagen aquí


8

C (gcc) , 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;}

Pruébalo en línea!

4n2+4n+101

C (gcc) , 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;}}

Pruébalo en línea!

4n2+4n+2×log10(2n+1)+9

Salida recortada para 20000:

salida recortada para 20000

Ambas versiones comienzan con el oeste y giran a la derecha en impar, izquierda en par.

Probé los casos de prueba más grandes con ninguno de ellos, ya que la salida con 20000 era ~ 1.5 GB, y 150000 habría sido ~ 90GB. Todo esto se almacena en la memoria mientras se ejecuta el programa.

Explicación de la superior:

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 */
}

1
No creo que se requiera que se proporcione un búfer asignado como argumento permitido: por meta política , cualquier entrada adicional debe estar vacía (lo que interpretaría como 0puntero nulo o medio en el caso de C).
Pomo de la puerta

3
Estoy interpretando esto como diciendo que puedo esperar que se asigne. Este también es un patrón utilizado en muchas funciones de biblioteca estándar, como sprintf.
wastl

Ah bien, tienes razón, eso tiene sentido.
Pomo de la puerta


8

Wolfram Language (Mathematica) , 98 96 91 77 76 63 bytes

ListPlot@AnglePath@Array[Pi/2If[PrimeQ@#,2ThueMorse@#-1,0]&,#]&

-14 bytes: Gracias a @lirtosiast por mostrarme cómo usarAnglePath ...

-13 bytes: ... y ThueMorse!

ejemplo de uso:

%[20000]

ingrese la descripción de la imagen aquí

Explicación paso a paso:

  • If[PrimeQ@#, 2 ThueMorse@# - 1, 0] &es una función que toma el índice de pasos y devuelve 0 para primos no primos, -1 para primos pares binarios y +1 para primos binarios impares. ThueMorse@#reemplaza la solución anterior Total[#~IntegerDigits~2](que es la misma, módulo 2).

  • Array[Pi/2*%,#]hace una lista de esta función con el índice que va del 1 al argumento de la función (20000 en el ejemplo) y multiplica cada elemento por π / 2 para convertirlo en un ángulo de cambio de dirección (radianes). Ahora tenemos 0 para no primos, -π / 2 para primos pares binarios, y + π / 2 para primos binarios impares.

  • AnglePath[%]convierte esta lista de ángulos de cambio de dirección en una ruta. Esta instrucción reemplaza el uso doble de la solución anterior Accumulate.

  • ListPlot[%]convierte la lista de posiciones en un diagrama de puntos XY. Si se prefiere una línea, use ListLinePloten su lugar. Estas funciones de trazado tienen muchas opciones para hacer que los trazados se vean mejor.


1
Gracias @lirtosiast! Es como aprender un idioma extranjero: vocabulario nuevo todos los días.
Romano

7

MATL, 31 30 28 26 bytes

J4:^0i:Zpl_G:B!s^*hYs)YsXG

3 bytes guardados gracias a @LuisMendo

2 bytes guardados gracias a @Sanchises

Pruébalo en MATL Online

Explicación

Esta solución utiliza números complejos para representar los componentes X e Y del plano 2D.

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]

En este punto, tenemos cuatro puntos ( (0, 1), (-1, 0), (0, -1), (1, 0)) en una matriz representada por números complejos. Estas son las cuatro direcciones cardinales. Ahora queremos usar estos para "caminar".

Esencialmente, la forma en que esto funciona es que comenzamos a dirigirnos en la dirección cero (el elemento 0 de la matriz que es (-1, 0)). Para cada paso, necesitamos determinar el cambio en este encabezado. Usaremos enteros para rastrear este cambio. Si queremos girar "a la derecha", incrementamos este número entero en 1 (haciendo referencia al siguiente elemento en la matriz de 4 puntos) y si queremos ir "a la izquierda", disminuimos este número entero en 1 (haciendo referencia al elemento anterior en el Matriz de 4 puntos). Si queremos continuar en nuestro camino, mantenemos constante el valor entero (haciendo referencia al mismo elemento en la matriz de 4 puntos).

Esta parte del código crea una matriz de todos aquellos 0, -1y 1los valores.

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

Ahora tenemos una matriz de las diferencias entre enteros sucesivos para poder calcular la suma acumulativa de esos para obtener los índices que luego podemos usar para buscar la dirección en cada paso en la matriz original de 4 elementos.

Convenientemente, MATL tiene una indexación envolvente de manera que el índice se 5ajusta al comienzo de una matriz de 4 elementos. Podemos usar esto a nuestro favor para poder incrementar y disminuir este número entero sin preocuparnos por el hecho de que la matriz de dirección de referencia es solo de 4 elementos.

Ys     % Compute the cumulative sum
)      % Use this to modularly index into the original array of four points

Ahora tenemos una serie de direcciones de pasos, por lo que podemos calcular la suma acumulativa de estas direcciones para trazar el camino que se tomó.

Ys     % Compute the cumulative sum
XG     % Plot as a 2D plot

5

Perl 6 , 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)}

Pruébalo en línea!

(¡Realmente logré reducir esto!)

Esta función sale en formato SVG.

  • { -{ .is-prime * .base(2).comb(~1) R** -1 || i }(++$)i } ... *es una secuencia infinita de cambios de dirección para cada paso, en forma de números complejos, donde 1significa "continuar en la misma dirección", isignifica "girar a la izquierda" y -isignifica "girar a la derecha".
  • [^$_] limita esa secuencia al número de pasos proporcionados como argumento de la función.
  • [\*] escanea esa secuencia con multiplicación (compleja), convirtiendo la lista de cambios de dirección relativa en una lista de direcciones absolutas.
  • [\+]escanea esa secuencia con la suma (compleja), produciendo una lista de las coordenadas visitadas.
  • ».reals convierte esa lista de números complejos en listas de dos elementos de sus partes reales e imaginarias.

La imagen SVG es solo un pathelemento único .

Salida (convertida a PNG) para N = 20000:

camino para N = 20000


4

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);}

Pruébalo en línea!

Comencé a trabajar en esto antes de que se publicara la otra respuesta C, pero pensé que podría publicar la mía también de todos modos. Este es mucho más largo, pero también recorta la imagen de salida a las dimensiones del resultado automáticamente.

La función se llama como f(n), y la salida es stdout en formato netpbm.

Ejemplo de salida para n = 1000:

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

La prueba principal es esencialmente la utilizada en la respuesta de Lynn a un desafío diferente , que se basa en el teorema de Wilson .

La prueba de paridad utiliza una adaptación del método de conteo de bits de Kernighan .

Dado que la prueba principal es muy lenta y el algoritmo vuelve a ejecutar la función de generación de ruta completa para cada píxel dibujado, cualquier entrada mucho más de 1000 veces en TIO.



4

LOGOTIPO, 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

Para usar, haga algo como esto :

reset
pu
fw 100
pd
g 3000

Lo siento, pero no pude capturar la salida de muestra. Explicación:

to d:c
if :c%2[rt 180
make"c:c-1]if:c<1[stop]d:c/2
end

Este es un procedimiento recursivo que gira 180 ° por cada bit establecido en su parámetro, que efectivamente calcula la paridad de su expansión binaria.

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

Esta es una prueba de primalidad muy básica. Después de la carcasa especial 1, el procedimiento regresa anticipadamente si se encuentra un factor. Sin embargo, si se encuentra que el valor actual es primo, gira a la derecha y luego utiliza el procedimiento anterior para cambiarlo a un giro a la izquierda según corresponda.

to g:n
make"c 1
repeat:n[p
fw 2
make"c:c+1]end

Este es solo un bucle simple para probar todos los números hasta nla originalidad y mover dos píxeles después de cada uno.


4

Jalea , 41 bytes

B§ḂḤ’×ıµ1Ẓ?€×\ÄŻÆiZ_Ṃ$€Z‘ḞŒṬµẈḢ⁾P1,;Lṭ@FK

Pruébalo en línea!

N

N=3000

Salida para N = 3000

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

4

JavaScript - 675 668 660 632 556 534 Bytes

Primera vez aquí en CodeGolf, inicialmente comenzó con ~ 1500 Bytes Code. Golfizado a menos de la mitad, casi más de un tercio. Siéntase libre de continuar jugando al golf. Bytes contados con: esta herramienta

Principio:
Dibuja en lienzo de tamaño fijo con N y longitud de trazo variable como entrada.

Ediciones:

-07 Bytes - elimine los perdidos si
-08 Bytes - cambie el interruptor a if / else
-28 Bytes - cambie a tenary if / else
-76 Bytes - prueba principal más corta (tiempo de ejecución / 3)
-22 Bytes - use esta función principal (tiempo de ejecución * 4)

Código de golf:

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}

Código sin campos con espacios en blanco:

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
}

Ejemplos:

N = 7 - Longitud = 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 - Longitud = 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 - Longitud = 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 - Longitud = 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"/> 


¿El color depende de la cantidad de líneas superpuestas? ¡Guay!
Val

No cambié el estilo de trazo, este debería ser el negro predeterminado sin patrón ni transparencia. Encontrado aquí . Por qué podría ocurrir un cambio de color podría estar relacionado con el ancho del trazo que configuré en el segundo parámetro, mi función toma @val. Perdón por decepcionarte.
pixma140

3

Rojo , 515 480 471 bytes

-1 byte gracias a 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]]]]]

Una parte importante del código (~ 160 bytes) se ocupa de normalizar las coordenadas para que los gráficos se ajusten completamente al lienzo, independientemente del tamaño de la entrada.

Dirección inicial: sur.

Aquí está el resultado para n = 3000

3000 iteraciones

n = 20000

20000


1
Por curiosidad, ¿por qué no hay espacios necesarios para los modulos en if j%(k + 1)y if j% 2 = 1, pero hay espacios requeridos para la mayoría de los otros operadores ( +, /, etc.). ¿Se puede eliminar también el espacio en el módulo de pick[-90 90]s% 2? En realidad, ¿por qué tampoco hay espacios necesarios as-pair k/1 - t * c k/2 - v * cpara /?
Kevin Cruijssen

1
@KevinCruijssen Sí, se puede quitar el espacio s% 2, ¡gracias! No sé por qué, pero el módulo %es el único operador para el que se puede eliminar el espacio delante de él, si está precedido por una palabra (variable). En as-pair k/1 - t * c k/2 - v * clas barras /sirven un propósito completamente diferente: son paths. kes una pairy k/1es el primer elemento (que puede ser seleccionada también por k/x, o pick k 1). Se necesitan espacios en casi todas partes, hay excepciones ()[]{}, porque no hay ambigüedad.
Galen Ivanov

@KevinCruijssen La mayoría de los símbolos se pueden usar en los wordnombres ( Redno tiene variables, todo es un wordvalor o (o algún bloque de sintaxis como [...]o (...)). Entonces: a*4: 45-> a una palabra a*4se le asigna un valor 45. %se usa como marcador para el file!tipo de datos y tal vez por eso no se puede usar en los wordnombres, pero puede romper las reglas para los otros operadores aritméticos.
Galen Ivanov

1
Ah, ok, tiene sentido que /tengan un propósito diferente allí y los símbolos se pueden usar sin espacios en las variables (o wordscomo aparentemente se llaman para el rojo). Gracias por la explicación. :) Y me alegro de haber podido (principalmente accidentalmente) guardar un byte para s% 2. :)
Kevin Cruijssen

1

Procesamiento, más de 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;);}

Podría no cumplir claramente visto

caminar

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.