Generar una espiral de Padua

34

Introducción

Similar a la secuencia de Fibonacci, la secuencia de Padovan ( OEIS A000931 ) es una secuencia de números que se produce al agregar términos anteriores en la secuencia. Los valores iniciales se definen como:

P(0) = P(1) = P(2) = 1

Los términos 0º, 1º y 2º son todos 1. La relación de recurrencia se establece a continuación:

P(n) = P(n - 2) + P(n - 3)

Por lo tanto, produce la siguiente secuencia:

1, 1, 1, 2, 2, 3, 4, 5, 7, 9, 12, 16, 21, 28, 37, 49, 65, 86, 114, 151, 200, 265, 351, ...

El uso de estos números como longitudes laterales de triángulos equiláteros produce una espiral agradable cuando los coloca todos juntos, al igual que la espiral de Fibonacci:

ingrese la descripción de la imagen aquí

Imagen cortesía de Wikipedia.


Tarea

Su tarea es escribir un programa que recrea esta espiral por salida gráfica, con la entrada correspondiente a qué término.

Reglas

  • Su envío debe ser capaz de manejar al menos hasta el décimo término (9)
  • Su envío debe ser un programa completo o una función que reciba información y muestre un resultado gráfico (ya sea que genere una imagen o gráficos, etc.)
  • Debe mostrar prueba de su salida gráfica en su envío
  • Se permiten rotaciones de la salida, en múltiplos de 60 grados, con la misma representación
  • Ir en sentido antihorario también está permitido
  • Las lagunas estándar están prohibidas

Puede suponer que la entrada será> 0 y que se dará el formato correcto de entrada.

Tanteo

Este es el , por lo que gana el código más corto en bytes. ¡Feliz Año Nuevo a todos!

Andrew Li
fuente
¿Se permite el espacio final después de las líneas?
Pavel
@Pavel Sí. Permítanme agregar eso
Andrew Li el
¿La salida tiene que ser idéntica al ejemplo o se permiten reflexiones y rotaciones (múltiplos de 60 grados)?
Level River St el
@LevelRiverSt Permitiría eso. Déjame aclarar eso en la publicación.
Andrew Li el
3
No soy fanático de permitir tanto el arte ASCII como la salida gráfica en el mismo desafío. Son tareas muy diferentes, y mezclarlas juntas hace que las respuestas resuelvan las dos posibilidades completamente completamente incomparables. Sería mejor tener dos desafíos separados, uno para el arte ASCII y otro para la salida gráfica.
Martin Ender

Respuestas:

12

Mathematica, 119108 bytes

¡Gracias a Martin Ender por guardar 11 bytes!

±n_:=If[n<4,1,±(n-2)+±(n-3)];Graphics@Line@ReIm@Accumulate@Flatten@{0,z=I^(2/3),±# z^(#+{2,4,1})&~Array~#}&@

Función sin nombre que toma un argumento entero positivo (1 indexado) y devuelve la salida de gráficos. Ejemplo de salida para la entrada 16:

ingrese la descripción de la imagen aquí

Desarrollado simultáneamente con la respuesta Matlab de flawr pero con muchas similitudes en el diseño, ¡incluso incluyendo la definición I^(2/3)de la sexta raíz de la unidad! Versión más fácil de leer:

1  (±n_:=If[n<4,1,±(n-2)+±(n-3)];
2   Graphics@Line@ReIm@
3   Accumulate@Flatten@
4   {0,z=I^(2/3),±# z^(#+{2,4,1})&~Array~#}
5  ])&

La línea 1 define la secuencia de Padovan ±n = P(n). La línea 4 crea una matriz anidada de números complejos, que se definen a lo zlargo del camino; la última parte ±# z^(#+{2,4,1})&~Array~#genera muchos triples, cada uno de los cuales corresponde a los vectores que necesitamos dibujar para completar el triángulo correspondiente ( ±#controla la longitud mientras z^(#+{2,4,1})controla las direcciones). La línea 3 elimina la anidación de la lista y luego calcula los totales acumulados de los números complejos, para convertir de vectores a coordenadas puras; la línea 2 luego convierte números complejos en pares ordenados de números reales y genera la línea poligonal correspondiente.

Greg Martin
fuente
1
no importa que parte fuera solo yo siendo estúpido.
Martin Ender
9

Matlab, 202 190 bytes

N=input('');e=i^(2/3);f=1/e;s=[0,e,1,f,-e,e-2];l=[1,1,1,2];M=N+9;T=[l,2:M-3;2:M+1;3:M+2];for k=5:N;l(k)=l(k-2)+l(k-3);s(k+2)=s(k+1)+e*l(k);e=e*f;end;T=[T;T(1,:)];plot(s(T(:,1:N)));axis equal

Salida para N=19(indexación basada en 1):

ingrese la descripción de la imagen aquí

Explicación

La idea aproximada es básicamente trabajar con números complejos. Entonces los bordes de los triángulos apuntan siempre en la dirección de una sexta raíz de la unidad.

N=input('');                         % Fetch input
e=i^(2/3);                           % 6th root of unity
f=1/e;                               %  "
s=[0,e,1,f,-e,e-2];                  % "s" is a list of vertices in the order as the spiral is defined
l=[1,1,1,2];                         % "l" is a list of edge-lengths of the triangles
for k=5:N;                           % if we need more values in "l"/"s" we calculate those
    l(k)=l(k-2)+l(k-3);
    s(k+2)=s(k+1)+e*l(k);
    e=e*f;
end;
M=N+9;
T=[[1,1,1,2,2:M-3];2:M+1;3:M+2]';    % this matrix describes which vertices from s are needed for each triangle (the cannonical way how meshes of triangles are stored)
trimesh(T(1:N,:),real(s),imag(s));   % plotting the mesh, according to "T"
axis equal
falla
fuente
¡Buen trabajo! ¿Hay alguna posibilidad de una explicación?
Andrew Li el
explicación agregada!
flawr
Me gusta mucho el uso de números complejos aquí.
Don brillante
7

PHP + SVG, 738 bytes

<?php
$a=[1,1,1];
for($i=0;$i<99;)$a[]=$a[$i]+$a[++$i];
$d=$e=$f=$g=$x=$y=0;
$c=[333,999];
$z="";
foreach($a as$k=>$v){
if($k==$_GET['n'])break;
$h=$v/2*sqrt(3);
if($k%6<1){$r=$x+$v/2;$s=$y+$h;$t=$r-$v;$u=$s;}
if($k%6==1){$r=$x-$v/2;$s=$y+$h;$t=$x-$v;$u=$y;}
if($k%6==2){$r=$x-$v;$s=$y;$t=$r+$v/2;$u=$y-$h;}
if($k%6==3){$r=$x-$v/2;$s=$y-$h;$t=$r+$v;$u=$s;}
if($k%6==4){$r=$x+$v/2;$s=$y-$h;$t=$r+$v/2;$u=$y;}
if($k%6>4){$r=$x+$v;$s=$y;$t=$r-$v/2;$u=$y+$h;}
$d=min([$d,$r,$t]);
$e=max([$e,$r,$t]);
$f=min([$f,$s,$u]);
$g=max([$g,$s,$u]); 
$p="M$x,{$y}L$r,{$s}L$t,{$u}Z";
$z.="<path d=$p fill=#{$c[$k%2]} />";
$x=$r;
$y=$s;
}
?>
<svg viewBox=<?="$d,$f,".($e-$d).",".($g-$f)?> width=100% height=100%>
<?=$z?>
</svg>

Salida para 16

<svg viewBox=-53,-12.124355652982,75.5,42.435244785437 width=100% height=100%>
<path d=M0,0L0.5,0.86602540378444L-0.5,0.86602540378444Z fill=#333 /><path d=M0.5,0.86602540378444L0,1.7320508075689L-0.5,0.86602540378444Z fill=#999 /><path d=M0,1.7320508075689L-1,1.7320508075689L-0.5,0.86602540378444Z fill=#333 /><path d=M-1,1.7320508075689L-2,0L0,0Z fill=#999 /><path d=M-2,0L-1,-1.7320508075689L0,0Z fill=#333 /><path d=M-1,-1.7320508075689L2,-1.7320508075689L0.5,0.86602540378444Z fill=#999 /><path d=M2,-1.7320508075689L4,1.7320508075689L0,1.7320508075689Z fill=#333 /><path d=M4,1.7320508075689L1.5,6.0621778264911L-1,1.7320508075689Z fill=#999 /><path d=M1.5,6.0621778264911L-5.5,6.0621778264911L-2,-8.8817841970013E-16Z fill=#333 /><path d=M-5.5,6.0621778264911L-10,-1.7320508075689L-1,-1.7320508075689Z fill=#999 /><path d=M-10,-1.7320508075689L-4,-12.124355652982L2,-1.7320508075689Z fill=#333 /><path d=M-4,-12.124355652982L12,-12.124355652982L4,1.7320508075689Z fill=#999 /><path d=M12,-12.124355652982L22.5,6.0621778264911L1.5,6.0621778264911Z fill=#333 /><path d=M22.5,6.0621778264911L8.5,30.310889132455L-5.5,6.0621778264911Z fill=#999 /><path d=M8.5,30.310889132455L-28.5,30.310889132455L-10,-1.7320508075689Z fill=#333 /><path d=M-28.5,30.310889132455L-53,-12.124355652982L-4,-12.124355652982Z fill=#999 /></svg>

Jörg Hülsermann
fuente
1
Dos cosas pequeñas para el golf: $k%6==0puede ser $k%6<1y $k%6==5puede ser $k%6>4.
Kevin Cruijssen
4

Python 3, 280 , 262 bytes

18 bytes guardados gracias a los ovs

Golfizado:

import turtle
P=lambda n:n<4or P(n-3)+P(n-2)
N=int(input())
M=9
t=turtle.Turtle()
Q=range
R=t.right
L=t.left
F=t.forward
S=[P(x)*M for x in Q(N,0,-1)]
A=S[0]
F(A)
R(120)
F(A)
R(120)
F(A)
L(120)
i=1
while i<N:
 A=S[i]
 for j in Q(3):F(A);L(120)
 F(A)
 L(60)
 i+=1

Lo mismo con algunos comentarios:

import turtle

# P(n) returns nth term in the sequence
P=lambda n:n<4or P(n-3)+P(n-2)

# M: scales the triangle side-length
M=9
# N: show triangles from 1 to (and including) N from sequence
N=int(input())
t=turtle.Turtle()
Q=range
R=t.right # R(a) -> turn right "a" degrees
L=t.left  # L(a) -> turn left "a" degrees
F=t.forward # F(l) -> move forward "l" units

# S: M*P(N),M*P(N-1), ... M*P(1)
S=[P(x)*M for x in Q(N,0,-1)]

# draw the largest triangle
A=S[0]
F(A)
R(120)
F(A)
R(120)
F(A)
L(120)
i=1

# draw the next N-1 smaller triangles
while i<N:
 A=S[i]
 for j in Q(3):F(A);L(120)
 F(A)
 L(60)
 i+=1

Captura de pantalla para N=9:

N = 9

Bobas_Pett
fuente
2

dwitter 151

s=(n)=>{P=(N)=>N<3||P(N-3)+P(N-2)
for(a=i=0,X=Y=500,x.moveTo(X,Y);i<n*4;i++)k=9*P(i/4),x.lineTo(X+=C(a)
*k,Y+=S(a)*k),x.stroke(),a+=i%4>2?1.047:2.094}

se puede probar en http://dwitter.net (usar pantalla completa)

ingrese la descripción de la imagen aquí

La idea básica es el logotipo de tortuga, golf. ¡Robó la función P () desde arriba!

Me imagino que se podría jugar más por recursión, pero esto no está mal.

don brillante
fuente
1

LOGOTIPO, 119 bytes

to s:n
make"x 10
make"y:x
make"z:y
bk:z
repeat:n[lt 60
fw:z
rt 120
fw:z
bk:z
make"w:y+:z
make"z:y
make"y:x
make"x:w]end

Para usar, haga algo como esto :

reset
lt 150
s 12

Salida de muestra (no se puede incrustar porque no es HTTPS y no se pudo cargar a imgur)

Neil
fuente