Générer une spirale de Padoue


34

introduction

Semblable à la séquence de Fibonacci, la séquence de Padoue ( OEIS A000931 ) est une séquence de nombres générée en ajoutant des termes précédents à la séquence. Les valeurs initiales sont définies comme suit:

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

Les 0ème, 1er et 2ème termes sont tous 1. La relation de récurrence est indiquée ci-dessous:

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

Ainsi, il en résulte la séquence suivante:

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

En utilisant ces nombres comme longueurs de côtés de triangles équilatéraux, vous obtenez une belle spirale lorsque vous les placez tous ensemble, un peu comme la spirale de Fibonacci:

entrez la description de l'image ici

Image reproduite avec l' aimable autorisation de Wikipedia


Tâche

Votre tâche consiste à écrire un programme qui recrée cette spirale par une sortie graphique, avec une entrée correspondant à quel terme.

Règles

  • Votre candidature doit pouvoir traiter au moins jusqu'au 10ème mandat (9)
  • Votre soumission doit être un programme complet ou une fonction qui prend une entrée et affiche un résultat graphique (soit une image ou des graphiques, etc.)
  • Vous devez montrer une preuve de votre sortie graphique dans votre soumission.
  • Les rotations de la sortie sont autorisées, par multiples de 60 degrés, avec la même représentation
  • Aller dans le sens anti-horaire est également autorisé
  • Les échappatoires standard sont interdites

Vous pouvez supposer que l'entrée sera> 0 et que le format d'entrée correct sera donné.

Notation

C'est le , donc le code le plus court en octets gagne. Bonne année à tous!


L'espace de fin après les lignes est-il autorisé?
Pavel

@Pavel Oui. Permettez-moi d'ajouter que
Andrew Li

La sortie doit-elle être identique à l'exemple ou les réflexions et les rotations (multiples de 60 degrés) sont-elles autorisées?
Level River St

@LevelRiverSt J'autoriserais cela. Laissez-moi clarifier cela dans le post.
Andrew Li

3
Pas un fan de permettre à la fois l'art ASCII et la sortie graphique dans le même défi. Ce sont des tâches très très différentes, et les mélanger ensemble rend les réponses permettant de résoudre les deux possibilités différentes totalement incomparables. Il serait préférable d’avoir deux défis distincts, un pour l’art ASCII et un pour la sortie graphique.
Martin Ender

Réponses:


12

Mathematica, 119 108 octets

Merci à Martin Ender d'avoir économisé 11 octets!

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

Fonction non nommée prenant un argument entier positif (indexé 1) et renvoyant une sortie graphique. Exemple de sortie pour l'entrée 16:

entrez la description de l'image ici

Développé simultanément avec la réponse Matlab de flawr, mais avec de nombreuses similitudes dans la conception, incluant même la définition I^(2/3)de la sixième racine de l'unité! Version plus facile à lire:

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 ligne 1 définit la séquence de Padoue ±n = P(n). La ligne 4 crée un tableau imbriqué de nombres complexes, définissant le zlong du chemin; la dernière partie ±# z^(#+{2,4,1})&~Array~#génère de nombreux triplets, chacun correspondant aux vecteurs à dessiner pour compléter le triangle correspondant (le ±#contrôle de la longueur et le z^(#+{2,4,1})contrôle de la direction). La ligne 3 supprime l'imbrication de la liste, puis calcule les totaux cumulés des nombres complexes, pour convertir les vecteurs en coordonnées pures; La ligne 2 convertit ensuite les nombres complexes en paires ordonnées de nombres réels et affiche la ligne polygonale correspondante.


1
Nevermind cette partie était juste moi d'être stupide.
Martin Ender

9

Matlab, 202 190 octets

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

Sortie pour N=19(indexation basée sur 1):

entrez la description de l'image ici

Explication

L'idée approximative est de travailler avec des nombres complexes. Ensuite, les arêtes des triangles pointent toujours dans la direction d'une sixième racine d'unité.

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

Bon travail! Y a-t-il une possibilité d'explication?
Andrew Li

Explication ajoutée!
mardi

vraiment comme l'utilisation de nombres complexes ici.
Don lumineux

7

PHP + SVG, 738 octets

<?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>

Sortie pour 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>


1
Deux petites choses au golf: $k%6==0peut être $k%6<1et $k%6==5peut être $k%6>4.
Kevin Cruijssen

4

Python 3, 280 , 262 octets

18 octets sauvés grâce à ovs

Golfé:

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

Même chose avec quelques commentaires:

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

Capture d'écran pour N=9:

N = 9


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}

peut être testé sur http://dwitter.net (utilisez le plein écran)

entrez la description de l'image ici

L'idée de base est logo tortue, golfée. a volé la fonction P () d'en haut!

J'imagine que plus de gens pourraient jouer au golf par récursivité, mais ce n'est pas mauvais.


1

LOGO, 119 octets

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

Pour utiliser, faire quelque chose comme ça :

reset
lt 150
s 12

Exemple de sortie (impossible d'intégrer car ce n'est pas HTTPS et le téléchargement dans imgur a échoué)

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.