Erzeugen Sie eine Padovan-Spirale

34

Einführung

Ähnlich wie die Fibonacci-Sequenz ist die Padovan-Sequenz ( OEIS A000931 ) eine Folge von Zahlen, die durch Hinzufügen vorheriger Ausdrücke in der Folge erzeugt wird. Die Anfangswerte sind definiert als:

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

Das 0., 1. und 2. Glied sind alle 1. Die Wiederholungsbeziehung ist unten angegeben:

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

Somit ergibt sich folgende Reihenfolge:

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

Wenn Sie diese Zahlen als Seitenlänge von gleichseitigen Dreiecken verwenden, erhalten Sie eine schöne Spirale, wenn Sie sie alle zusammen platzieren, ähnlich wie bei der Fibonacci-Spirale:

Bildbeschreibung hier eingeben

Bild mit freundlicher Genehmigung von Wikipedia


Aufgabe

Ihre Aufgabe ist es, ein Programm zu schreiben, das diese Spirale durch grafische Ausgabe wiederherstellt, wobei die Eingabe dem jeweiligen Begriff entspricht.

Regeln

  • Ihr Beitrag muss mindestens bis zur 10. Amtszeit bearbeitet werden können (9)
  • Ihre Einreichung muss ein vollständiges Programm oder eine vollständige Funktion sein, die Eingaben entgegennimmt und ein grafisches Ergebnis anzeigt (entweder ein Bild oder Grafiken usw.).
  • Sie müssen in Ihrer Einreichung einen Nachweis Ihrer grafischen Ausgabe vorlegen
  • Die Drehung der Ausgabe ist in 60-Grad-Vielfachen mit derselben Darstellung zulässig
  • Es ist auch erlaubt, gegen den Uhrzeigersinn zu fahren
  • Standardlücken sind verboten

Sie können davon ausgehen, dass die Eingabe> 0 ist und das richtige Eingabeformat angegeben wird.

Wertung

Das ist , also gewinnt der kürzeste Code in Bytes. Ein frohes neues Jahr euch allen!

Andrew Li
quelle
Darf nach Zeilen ein Leerzeichen stehen?
Pavel
@Pavel Ja. Lassen Sie mich das hinzufügen
Andrew Li
Muss die Ausgabe mit dem Beispiel identisch sein oder sind Reflexionen und Rotationen (Vielfache von 60 Grad) zulässig?
Level River St
@LevelRiverSt Das würde ich zulassen. Lassen Sie mich das in der Post klarstellen.
Andrew Li
3
Kein Fan von ASCII-Grafik und Grafikausgabe in derselben Herausforderung. Es handelt sich um sehr unterschiedliche Aufgaben, und durch das Zusammenmischen von Antworten werden die beiden unterschiedlichen Möglichkeiten völlig unvergleichlich gelöst. Es wäre besser, zwei separate Herausforderungen zu haben, eine für ASCII-Grafik und eine für grafische Ausgabe.
Martin Ender

Antworten:

12

Mathematica, 119 108 Bytes

Vielen Dank an Martin Ender für die Einsparung von 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~#}&@

Unbenannte Funktion, die ein positives ganzzahliges Argument (1-indiziert) verwendet und die Grafikausgabe zurückgibt. Beispielausgabe für die Eingabe 16:

Bildbeschreibung hier eingeben

Entwickelt gleichzeitig mit der Matlab-Antwort von flawr, aber mit vielen Ähnlichkeiten im Design - einschließlich der Definition I^(2/3)der sechsten Wurzel der Einheit! Einfacher zu lesende Version:

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  ])&

Zeile 1 definiert die Padovan-Sequenz ±n = P(n). Zeile 4 erstellt ein verschachteltes Array komplexer Zahlen, die zauf dem Weg definiert werden. Der letzte Teil ±# z^(#+{2,4,1})&~Array~#erzeugt viele Tripel, von denen jedes den Vektoren entspricht, die wir zeichnen müssen, um das entsprechende Dreieck zu vervollständigen (das ±#steuert die Länge, während das z^(#+{2,4,1})die Richtungen steuert). Zeile 3 beseitigt die Listenverschachtelung und berechnet dann die laufenden Summen der komplexen Zahlen, um sie von Vektoren in reine Koordinaten umzuwandeln. Zeile 2 konvertiert dann komplexe Zahlen in geordnete Paare reeller Zahlen und gibt die entsprechende polygonale Linie aus.

Greg Martin
quelle
1
egal, dieser Teil war nur, dass ich dumm war.
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

Ausgabe für N=19(1-basierte Indizierung):

Bildbeschreibung hier eingeben

Erläuterung

Die grobe Idee besteht im Wesentlichen darin, mit komplexen Zahlen zu arbeiten. Dann zeigen die Kanten der Dreiecke immer in Richtung einer sechsten Einheitswurzel.

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
fehlerhaft
quelle
Gute Arbeit! Gibt es eine Erklärungsmöglichkeit?
Andrew Li
Erklärung hinzugefügt!
Fehler
mag die Verwendung von komplexen Zahlen hier wirklich.
Don Bright
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>

Ausgang für 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
quelle
1
Zwei kleine Dinge zum Golfen: $k%6==0Kann sein $k%6<1und $k%6==5kann sein $k%6>4.
Kevin Cruijssen
4

Python 3, 280 , 262 Bytes

18 Bytes gespart dank ovs

Golf gespielt:

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

Gleiches mit einigen Kommentaren:

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

Screenshot für N=9:

N = 9

Bobas_Pett
quelle
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}

kann auf http://dwitter.net getestet werden (Vollbild verwenden)

Bildbeschreibung hier eingeben

Grundidee ist Logo Schildkröte, Golf. hat die P () -Funktion von oben gestohlen!

Ich stelle mir vor, dass durch Rekursion mehr Golf gespielt werden könnte, aber das ist nicht schlecht.

Don Bright
quelle
1

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

Gebrauch, so etwas wie dies :

reset
lt 150
s 12

Beispielausgabe (kann nicht eingebettet werden, da es sich nicht um HTTPS handelt und das Hochladen nach imgur fehlgeschlagen ist)

Neil
quelle