파도바 나선형 생성


34

소개

피보나치 수열과 유사하게 파도바 수열 ( OEIS A000931 )은 수열에 이전 항을 추가하여 생성되는 수열입니다. 초기 값은 다음과 같이 정의됩니다.

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

0, 1, 2 번째 항은 모두 1입니다. 반복 관계는 다음과 같습니다.

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

따라서 다음과 같은 시퀀스가 ​​생성됩니다.

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

이 숫자를 정삼각형의 측면 길이로 사용하면 피보나치 나선과 같이 모두 함께 배치 할 때 멋진 나선을 얻을 수 있습니다.

여기에 이미지 설명을 입력하십시오

Wikipedia의 이미지 제공


태스크

당신의 임무는 그래픽 용어 로이 나선을 재현하는 프로그램을 작성하는 것입니다.

규칙

  • 귀하의 제출물은 최소한 10 학기까지 처리 할 수 ​​있어야합니다 (9).
  • 제출물은 입력을 받고 그래픽 결과를 표시하는 전체 프로그램 또는 기능이어야합니다 (이미지 또는 그래프 출력 등).
  • 제출시 그래픽 출력 증명을 보여 주어야합니다.
  • 출력의 회전은 동일한 표현으로 60도 배수로 허용됩니다.
  • 반 시계 방향으로도 이동 가능
  • 표준 허점 은 금지되어 있습니다

입력이> 0이고 올바른 형식의 입력이 있다고 가정 할 수 있습니다.

채점

이것은 이므로 바이트 단위의 가장 짧은 코드가 이깁니다. 새해 복 많이 받으세요!


줄 뒤에 공백이 허용됩니까?
Pavel

@Pavel 예. 내가 그를 추가하자
앤드류 리

출력이 예제와 동일해야합니까, 아니면 반사 및 회전 (60 도의 배수)이 허용됩니까?
Level River St

@LevelRiverSt 허용합니다. 게시물에서 그것을 명확히하겠습니다.
Andrew Li

3
ASCII 아트와 그래픽 출력을 모두 같은 도전으로 허용하는 팬은 아닙니다. 그것들은 매우 다른 작업이며, 그것들을 혼합하면 두 가지 다른 가능성을 완전히 비교할 수없는 답변을 얻습니다. ASCII 아트와 그래픽 출력에 대한 두 가지 과제를 갖는 것이 좋습니다.
Martin Ender

답변:


12

Mathematica, 119108 바이트

11 바이트를 절약 한 Martin Ender에게 감사합니다!

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

명명되지 않은 함수는 양의 정수 인수 (1 색인)를 사용하여 그래픽 출력을 반환합니다. 입력의 출력 예 16:

여기에 이미지 설명을 입력하십시오

flawr의 Matlab 답변을 사용 하여 동시에 개발 되었지만 디자인의 유사성은 여러 가지로 유사합니다 I^(2/3). 더 읽기 쉬운 버전 :

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

라인 1은 파도바 시퀀스를 정의합니다 ±n = P(n). 4 번째 줄은 복잡한 숫자의 중첩 배열을 만들어 z길을 따라 정의 합니다. 마지막 부분 ±# z^(#+{2,4,1})&~Array~#은 많은 트리플을 생성하는데, 각 트리플은 해당 삼각형을 완성하기 위해 그려야하는 벡터에 해당 ±#합니다 (길이는 z^(#+{2,4,1})제어하지만 방향 은 제어). 3 행은리스트 중첩을 제거한 다음 복소수의 누계를 계산하여 벡터에서 순수한 좌표로 변환합니다. 그런 다음 line 2는 복소수를 정렬 된 실수 쌍으로 변환하고 해당 다각형 선을 출력합니다.


1
그 부분은 내가 바보라고 생각하지 않았다.
Martin Ender

9

MATLAB, 202 190 바이트

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

N=19(1 기반 색인)에 대한 출력 :

여기에 이미지 설명을 입력하십시오

설명

대략적인 아이디어는 기본적으로 복잡한 숫자를 사용하는 것입니다. 그런 다음 삼각형의 가장자리는 항상 여섯 번째 단일 근의 방향을 가리 킵니다.

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

좋은 작업! 설명의 가능성이 있습니까?
Andrew Li

설명이 추가되었습니다!
flawr

여기서 복잡한 숫자를 사용하는 것이 정말 좋습니다.
밝게 돈

7

PHP + SVG, 738 바이트

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

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
골프를 치기위한 두 가지 작은 것들 : $k%6==0있을 수 $k%6<1있고 $k%6==5있을 수 있습니다 $k%6>4.
Kevin Cruijssen

4

파이썬 3, 280 , 262 바이트

ovs 덕분에 18 바이트 절약

골프 :

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

몇 가지 코멘트와 같은 것 :

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

스크린 샷 N=9:

N = 9


2

산산조각 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}

http://dwitter.net에서 테스트 할 수 있습니다 (전체 화면 사용)

여기에 이미지 설명을 입력하십시오

기본 아이디어는 로고 거북이, 골프입니다. 위에서 P () 함수를 훔쳤습니다!

나는 재귀로 더 많은 골프를 칠 수 있다고 생각하지만 이것은 나쁘지 않습니다.


1

로고, 119 바이트

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

사용하려면 다음과 같이 하십시오 .

reset
lt 150
s 12

샘플 출력 (HTTPS가 아니고 이미지를 업로드하지 못하여 포함 할 수 없음)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.