Gere uma espiral de Padovan


34

Introdução

Semelhante à Sequência de Fibonacci, a Sequência Padovan ( OEIS A000931 ) é uma sequência de números produzida pela adição de termos anteriores na sequência. Os valores iniciais são definidos como:

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

Os 0º, 1º e 2º termos são todos 1. A relação de recorrência é declarada abaixo:

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

Assim, produz a seguinte sequência:

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

Usar esses números como comprimentos laterais de triângulos equilaterais produz uma espiral agradável quando você os junta, como a Espiral de Fibonacci:

insira a descrição da imagem aqui

Imagem cortesia da Wikipedia


Tarefa

Sua tarefa é escrever um programa que recria essa espiral por saída gráfica, com entrada correspondente a qual termo.

Regras

  • Seu envio deve ser capaz de lidar com pelo menos até o 10º período (9)
  • Seu envio deve ser um programa ou função completo que receba informações e exiba um resultado gráfico (gera uma imagem ou gráficos, etc.)
  • Você deve mostrar a prova de sua saída gráfica em seu envio
  • São permitidas rotações da saída, em múltiplos de 60 graus, com a mesma representação
  • Também é permitido ir no sentido anti-horário
  • As brechas padrão são proibidas

Você pode assumir que a entrada será> 0 e que o formato correto da entrada será fornecido.

Pontuação

Isso é , então o código mais curto em bytes vence. Feliz ano novo a todos!


O espaço à direita após as linhas é permitido?
Pavel

@Pavel Sim. Deixe-me acrescentar que
Andrew Li

A saída precisa ser idêntica ao exemplo ou são permitidos reflexos e rotações (múltiplos de 60 graus)?
Level River St

@LevelRiverSt Eu permitiria isso. Deixe-me esclarecer isso no post.
Andrew Li

3
Não é um fã de permitir tanto a arte ASCII quanto a produção gráfica no mesmo desafio. São tarefas muito muito diferentes, e misturá-las faz com que as respostas resolvam as duas possibilidades diferentes completamente incomparáveis. Seria melhor ter dois desafios separados, um para arte ASCII e outro para saída gráfica.
Martin Ender

Respostas:


12

Mathematica, 119 108 bytes

Agradecemos a Martin Ender por salvar 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~#}&@

Função sem nome, usando um argumento inteiro positivo (indexado a 1) e retornando saída gráfica. Exemplo de saída para a entrada 16:

insira a descrição da imagem aqui

Desenvolvido simultaneamente com a resposta do Matlab da flawr, mas com muitas semelhanças no design - incluindo inclusive a definição I^(2/3)para a sexta raiz da unidade! Versão mais fácil de ler:

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

A linha 1 define a sequência de Padovan ±n = P(n). A linha 4 cria uma matriz aninhada de números complexos, definindo zao longo do caminho; a última parte ±# z^(#+{2,4,1})&~Array~#gera muitos triplos, cada um dos quais corresponde aos vetores que precisamos desenhar para completar o triângulo correspondente (ele ±#controla o comprimento enquanto z^(#+{2,4,1})controla as direções). A linha 3 se livra do aninhamento da lista e calcula os totais em execução dos números complexos, para converter de vetores em coordenadas puras; a linha 2 converte números complexos em pares ordenados de números reais e gera a linha poligonal correspondente.


1
deixa pra lá essa parte era só eu sendo idiota.
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

Saída para N=19(indexação baseada em 1):

insira a descrição da imagem aqui

Explicação

A idéia aproximada é basicamente trabalhar com números complexos. Então as arestas dos triângulos apontam sempre na direção de uma sexta raiz da unidade.

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

Bom trabalho! Existe alguma possibilidade de explicação?
Andrew Li

explicação adicionada!
flawr

realmente gosto do uso de números complexos aqui.
315 don 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>

Saída 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>


1
Duas pequenas coisas para o golfe: $k%6==0pode ser$k%6<1 e $k%6==5podem ser $k%6>4.
21717 Kevin Murrijssen

4

Python 3, 280 , 262 bytes

18 bytes salvos graças a ovs

Golfe:

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

A mesma coisa com alguns comentários:

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 tela para 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}

pode ser testado em http://dwitter.net (use tela cheia)

insira a descrição da imagem aqui

idéia básica é logotipo tartaruga, golfed. roubou a função P () de cima!

Eu imagino que mais poderia ser jogado por recursão, mas isso não é ruim.


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

Para usar, fazer algo parecido com isso :

reset
lt 150
s 12

Saída de amostra (não é possível incorporar porque não é HTTPS e não foi possível carregar no imgur)

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.