Hemos tenido un par de desafíos sobre la espiral de Ulam. Pero eso no es suficiente.
En este desafío, trazaremos una espiral de Ulam triangular (en oposición a la espiral de Ulam cuadrada habitual). Aquí hay un bosquejo de cómo se ve la espiral.
Como sabemos, la espiral de Ulam organiza todos los números naturales en una espiral externa, y marca solo aquellos que son primos. Entonces, en el boceto anterior, solo se mostrarán los números que aparecen en negro (los primos).
El reto
Acepte un número N como entrada y muestre la espiral triangular de Ulam hasta ese número.
- La entrada puede ser stdin o argumento de función.
- La espiral debe girar en la dirección positiva (es decir, en sentido antihorario), como en la figura anterior.
- Cualquiera de los giros de 120 grados de la figura anterior sería válido, y el giro puede ser diferente para diferentes entradas. Pero el lado más bajo de los triángulos implícitos debe ser horizontal, ya que los únicos giros permitidos son (múltiplos de) 120 grados.
- El código debería ejecutarse teóricamente (con suficiente tiempo y memoria) para cualquier N hasta lo permitido por cualquier cálculo intermedio que realice con su tipo de datos predeterminado.
double
es suficiente; sin necesidad de tipos enteros grandes. - Todas las funciones incorporadas permitidas.
- No aceptaré mi propia respuesta (no creo que sea la más corta de todos modos ...).
Formatos de salida
Elija cualquiera de los siguientes.
Muestre un gráfico con un marcador (punto, círculo, cruz, lo que prefiera) en números primos y nada en números no primos. La escala no necesita ser la misma para los dos ejes. Es decir, los triángulos implícitos no necesitan ser equiláteros. Los ejes, las líneas de cuadrícula y las etiquetas de eje son opcionales. Solo se requieren los marcadores en los números primos.
Un resultado de ejemplo para N = 12 sería el siguiente (compárelo con el bosquejo anterior). El segundo gráfico es un ejemplo más interesante, correspondiente a N = 10000.
- Produzca un archivo de imagen con lo anterior, en cualquier formato de imagen conocido (como png, tiff, bmp).
Muestre la espiral como arte ASCII , utilizando un solo carácter de su elección para primos y espacio en blanco para no primos, con un espacio en blanco para separar las posiciones numéricas en la misma fila. Se permiten espacios iniciales o finales o nuevas líneas. Por ejemplo, el caso N = 12 usando
o
como carácter seríao · · · o · o · · · o · o
donde, por supuesto, solo
o
se mostrará la marca en los números primos. El·
al no primos se muestra aquí sólo por referencia.
Criterio ganador
La recompensa real es ver por ti mismo esos increíbles patrones. Código de golf, el código más corto gana.
fuente
Respuestas:
CJam,
4942 bytesIngrese como un entero entero en STDIN. Salida como una cuadrícula ASCII con
0
primos. La rotación de la espiral no es consistente: el mayor número de la espiral siempre estará en la fila inferior.Pruébalo aquí.
Explicación
La idea básica es representar el triángulo como una matriz 2D irregular mientras se realiza el cálculo. Obtiene esta matriz invirtiendo las líneas y alineando todas las filas a la izquierda:
Sería representado como
Como hemos reflejado la línea, queremos enrollar la espiral en sentido horario . Eso es conveniente, porque todo lo que tenemos que hacer es rotar el triángulo en sentido antihorario y anteponer la siguiente sublista en orden. Podemos rotar la matriz irregular invirtiendo todas las líneas y transponiéndola:
Entonces aquí está el código. Un detalle al que me gustaría llamar la atención es el último bit que crea el diseño triangular. Creo que es bastante ingenioso. :)
fuente
MATL ,
4836 bytesUtiliza la versión actual (9.3.0) .
Pruébalo en línea!
No tengo idea de cómo el compilador en línea logra traducir la salida gráfica a ASCII, pero lo hace. ¡Esto produce un diagrama ASCII aproximado gracias a una característica de octava que es compatible con el compilador en línea!Editar (4 de abril de 2016): la función
Y[
ha cambiado de nombrek
desde la versión 13.0.0. El enlace al compilador en línea incorpora este cambio, de modo que el código se puede probar.Ejemplo
produce la salida gráfica (se muestra la versión de MATLAB):
Explicación
El código usa números complejos para trazar la ruta seguida por la espiral. Como se puede ver en la primera figura del desafío, cada tramo recto de la espiral es un segmento con una longitud creciente 1, 2, 3, 4 ... y una orientación que aumenta cíclicamente 120 grados, 240 grados, 0 grados, 120 grados. ..
El código primero genera los desplazamientos complejos individuales de cada número entero al siguiente. Estos desplazamientos complejos tienen magnitud 1 y ángulo
2*pi/3
,4*pi/3
o0
(en radianes). Por lo tanto, se pueden generar fácilmente como exponenciales imaginarios. Para eso, la secuencia entera 0,1,2,2,3,3,3,4,4,4,4 ... se usa primero.Esta secuencia entera es casi como la secuencia "n aparece n veces" ( OEIS A002024 ), y se puede obtener como
floor(sqrt(2*n)+.5)
donden
es 0,1,2,3, .... Multiplicar por2j*pi/3
, dondej
está la unidad imaginaria, produce los desplazamientos complejos deseados.Los desplazamientos se acumulan para calcular las posiciones correspondientes a los números enteros en la espiral. El primer número entero en la espiral, que es
1
, está ubicado arbitrariamente en una posición1
en el plano complejo.Finalmente, las posiciones correspondientes a números no primos se descartan, y el resto se traza en el plano complejo.
fuente
.png
MATL descargue automáticamente las imágenes en un archivo que se mostrará en la página web @AlexAplot(1:5)
) y produce resultados gráficos de texto! matl.tryitonline.net/#code=NTpYRw&input= @AlexA. ¿¿Cómo es esto??El dibujo debe hacerse con
LaTeX / PGF, 527
594bytes527 bytes es el documento completo como arriba, es decir, incluye preámbulo y parámetro (aquí 4000, entonces ~ 523 sin parámetro). Produce un archivo PDF.
Idea básica: bueno, solo dibuja. Utiliza una transformación matricial para una cuadrícula triangular. El único problema es que también los puntos se ven afectados (y estirados) por la transformación. Así que elijo los marcadores de elipse :) lo que quiero decir con eso está claro en la segunda imagen (n = 250, 5pt).
Otra advertencia: solo puede manejar hasta un poco menos de 5000 debido al tamaño máximo de pila de TeX. La primera imagen es para n = 4000. Aparentemente es posible aumentar el tamaño de la pila , no lo intenté.
Utiliza PGF's
isprime()
.Sin golf:
fuente
lualatex
u otro compilador de asignación dinámica debería permitirle omitir el tamaño de la pila, si entiendo su comentario correspondiente correctamente. Por lo tanto, no es una limitación de su respuesta, solo de la mayoría de las implementaciones donde la ejecutaría.Mathematica, 94 bytes
Resultado
fuente
Python, 263 bytes
Siendo nuevo en Python, seguramente hay margen de mejora :)
Ejemplo:
fuente
s=[];X=[];Y=[];i=1;x=0;y=0
as=X=Y=[];i=1;x=y=0;
x=y=0
.R, 137 bytes
Utiliza solo funciones integradas, incluso para números primos. Dado su enfoque vectorizado en lugar de iterativo, es rápido, pero no puede manejar grandes cantidades.
Golfizado:
Sin golf:
Ejemplo:
fuente