El propósito de este desafío es representar gráficamente una caminata en el plano, donde la dirección de cada paso está determinada por la primalidad de 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 puede ser Norte, Oeste, Sur u Este, y se determina de la siguiente manera:
- Si no es primo, la dirección no cambia.
- Si es primo y la expansión binaria de tiene un número par, gire a la derecha.
- Si es primo y la expansión binaria de tiene un número impar, gire a la izquierda.
Como ejemplo trabajado , suponga que la dirección inicial es Norte. Los primeros pasos son:
- no es primo. Entonces nos movemos un paso en la dirección actual, que es Norte.
- es primo, y su expansión binaria
10
, 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. - es primo, y su expansión binaria
11
, 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. - no es primo. Entonces nos movemos un paso en la dirección actual, que es Norte.
El reto
Entrada : entero positivo .
Salida : diagrama de la caminata -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 .
- 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 .
- 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
N
recurso ilimitado dado. Es aceptable si en la práctica falla por muchoN
tiempo 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
:
N = 3000
:
N = 20000
:
N = 159000
:
N = 1200000
:
N = 11000000
:
code-golf
graphical-output
integer
primes
Luis Mendo
fuente
fuente
[graphical-output]
esté permitida? ¿Alguna razón en particular para la salida ASCII no permitida, como mi respuesta Charcoal ahora eliminada?Respuestas:
Sledgehammer 0.4 ,
2220 bytesSe descomprime en esta función Wolfram Language:
Sin golf
Primero definimos una función que devuelve el ángulo para girar en cada paso:
ThueMorse
es la paridad de la suma de dígitos binarios. Usamos en-1^(...)
lugar de2*...-1
por 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 como2/x
se almacenan comoTimes[2, Power[x, -1]]
. Esto hace que la frecuencia seaPower
muy alta y, por lo tanto, comprimirla es muy barata.(Multiplicar por
Boole@PrimeQ@
es un poco más largo, y elBoole
lanzamiento implícito de booleanos no se había implementado en el momento del desafío).Desde aquí, Mathematica's
AnglePath
yListPlot
hacemos exactamente lo que necesitamos:En la aplicación interactiva, la salida es un objeto de gráficos vectoriales reescalable.
fuente
MATL ,
252421 bytesPrué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
fuente
C (gcc) , 179 bytes
Pruébalo en línea!
0
1
C (gcc) , 219 bytes
Pruébalo en línea!
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:
fuente
0
puntero nulo o medio en el caso de C).Wolfram Language (Mathematica) ,
989691777663 bytes-14 bytes: Gracias a @lirtosiast por mostrarme cómo usar
AnglePath
...-13 bytes: ... y
ThueMorse
!ejemplo de uso:
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 anteriorTotal[#~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 anteriorAccumulate
.ListPlot[%]
convierte la lista de posiciones en un diagrama de puntos XY. Si se prefiere una línea, useListLinePlot
en su lugar. Estas funciones de trazado tienen muchas opciones para hacer que los trazados se vean mejor.fuente
MATL,
31302826 bytes3 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.
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
,-1
y1
los valores.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
5
ajusta 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.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ó.
fuente
Perl 6 ,
213182 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)}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, donde1
significa "continuar en la misma dirección",i
significa "girar a la izquierda" y-i
significa "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
path
elemento único .Salida (convertida a PNG) para N = 20000:
fuente
C, 321 bytes
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:
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.
fuente
LOGOTIPO,
177171 bytesPara usar, haga algo como esto :
Lo siento, pero no pude capturar la salida de muestra. Explicación:
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.
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.
Este es solo un bucle simple para probar todos los números hasta
n
la originalidad y mover dos píxeles después de cada uno.fuente
Jalea , 41 bytes
Pruébalo en línea!
fuente
JavaScript -
675668660632556534 BytesPrimera vez aquí en CodeGolf, inicialmente comenzó con ~ 1500 Bytes Code. Golfizado a
menos de la mitad,casimás de un tercio. Siéntase libre de continuar jugando al golf. Bytes contados con: esta herramientaPrincipio:
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:
Código sin campos con espacios en blanco:
Ejemplos:
fuente
Rojo ,
515480471 bytes-1 byte gracias a Kevin Cruijssen!
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
n = 20000
fuente
if j%(k + 1)
yif 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 depick[-90 90]s% 2
? En realidad, ¿por qué tampoco hay espacios necesariosas-pair k/1 - t * c k/2 - v * c
para/
?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). Enas-pair k/1 - t * c k/2 - v * c
las barras/
sirven un propósito completamente diferente: sonpath
s.k
es unapair
yk/1
es el primer elemento (que puede ser seleccionada también pork/x
, opick k 1
). Se necesitan espacios en casi todas partes, hay excepciones()[]{}
, porque no hay ambigüedad.word
nombres (Red
no tienevariables
, todo es unword
valor o (o algún bloque de sintaxis como[...]
o(...)
). Entonces:a*4: 45
-> a una palabraa*4
se le asigna un valor 45.%
se usa como marcador para elfile!
tipo de datos y tal vez por eso no se puede usar en losword
nombres, pero puede romper las reglas para los otros operadores aritméticos./
tengan un propósito diferente allí y los símbolos se pueden usar sin espacios en las variables (owords
como aparentemente se llaman para el rojo). Gracias por la explicación. :) Y me alegro de haber podido (principalmente accidentalmente) guardar un byte paras% 2
. :)Procesamiento, más de 140 bytes
Podría no cumplir claramente visto
fuente