나는 피타고라스 나무를 좋아한다


17

... 이것은 나를 나무로 만드는 도전입니다.

단일 정수 인수 N을 사용하고 피타고라스 나무 N 레벨을 깊게 그리는 트리라는 프로그램 또는 함수를 생성합니다. 여기서 레벨 0은 트렁크입니다.

나무의 각 접합점은 삼각형의 꼭짓점을 둘레의 임의의 지점에 배치해야합니다 (이 지점은 적어도 5 개의 동일한 간격으로 점 또는 전체 반원에 균일하게 분포되어야합니다).

선택적으로 당신의 나무는 시간에 따라 3d, 다채 롭거나 밝을 수 있습니다. 그러나 이것은 코드 골프이므로 가장 작은 파일이 이깁니다.

편집 : 나는 대회를 종료하고 일주일이되면 가장 작은 답변을 수락합니다


중복 된 것으로 보입니다
DavidC

그릇된. 나는 다른 알고리즘 : 후 해요
알렉산더 - 브렛

확인. 그럴 수 있지. "피타고라스 나무"에 대한 제출을 중단하는 것이 좋습니다.
DavidC

나는 기차를 좋아하는? :)
tomsmeding

답변:


15

매스 매 티카, 246 234 221 자

g[n_,s_:1]:={p=RandomReal[q=Pi/2],r=##~Rotate~(o={0,0})&,t=Translate}~With~If[n<0,{},Join[#~t~{0,s}&/@(#~r~p&)/@g[n-1,s*Cos@p],t[#,s{Cos@p^2,1+Sin[2p]/2}]&/@(r[#,p-q]&)/@g[n-1,s*Sin@p],{Rectangle[o,o+s]}]]
f=Graphics@g@#&

이것이 가장 우아하고 짧은 방법은 아닙니다.

용법: f[8]

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

여기에서 예를 들어 출력으로서 f[6]f[10]각각이.

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

언 골프 :

g[n_, s_:1] := With[{p},
  r = Rotate;
  t = Translate;
  p = RandomReal[q = Pi/2];
  If[n < 0, {},
   Join[
    (t[#, {0, s}] &) /@ (r[#, p, {0, 0}] &) /@ g[n - 1, s*Cos[p]],
    (t[#, s {Cos[p]^2, 1 + Sin[2 p]/2}] &) /@ (r[#, p - q, {0, 0}] &) /@
       g[n - 1, s*Sin[p]],
    {Rectangle[{0, 0}, {s, s}]}
    ]
   ]
  ]
f = Graphics@g[#] &

꽤 인상적입니다. 수치심 테스트 할 수있는 수학이 없습니다. 또 다른 몇 가지 예제 출력을 추가 할 수 있습니까?
alexander-brett

@ ali0sha 참조 편집
마틴 엔더

Show거기에 필요하지 않으며 필요하지 않습니다 Module.
swish

@swish Show힌트를 주셔서 감사 하지만 어떻게 제거 할 수 Module있습니까? p로컬을 선언하지 않으면 재귀 호출로 덮어 쓰므로 동일한 호출로 두 호출을 모두 수행 할 수 없었 p습니까?
Martin Ender

@ m.buettner Block보다 짧은을 사용할 수 있습니다 Module.
alephalpha

20

CFDG, 134 자

재귀 깊이를 제한 할 수 없기 때문에 이것은 정확히 유효하지 않습니다. 그러나 문제는 단지 이것 에 대한 해결책을 요구 합니다 . :)

startshape t
c(q)=cos(q/2)^2
d(q)=1+sin(q)/2
p=acos(-1)
shape t{w=rand(p)
SQUARE[x .5 .5]t[trans 0 1 c(w) d(w)]t[trans c(w) d(w) 1 1]}

결과는 다음과 같습니다

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

다른 46 자 ( 총 180 자 )의 경우 다음과 같이 채색 할 수도 있습니다.

startshape t
c(q)=cos(q/2)^2
d(q)=1+sin(q)/2
p=acos(-1)
shape t{w=rand(p)
SQUARE[x .5 .5 h 25 sat 1 b .2]t[trans 0 1 c(w) d(w) b .08 .8 h 2.2]t[trans c(w) d(w) 1 1 b .08 .8 h 2.2]}

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


나는 이것이 완전히 주제가 아니라는 것을 알고 있지만 "화이트 노이즈"대신 "브라운 노이즈"를 각도로 사용하면 버전이 어떻게 보일까요?
ɐɔıʇǝɥʇuʎs

@ Synthetica 0과 180에서 더 많은 각도로 90 ° 이하의 각도를 의미합니까?
Martin Ender

@Synthetica 이것과 유사합니다 . 실제 랜덤 워크 노이즈를 구현할 수 없었습니다. 입력 매개 변수 (마지막 임의의 값)를 가져 와서 조정하고 전달해야하기 때문입니다. 이것은 문법을 문맥에 민감하게 만들어 CFDG에서 지원하지 않습니다. 무작위 샘플에서 간단한 입방 함수를 사용하여 임의의 값을 π / 2쪽으로 조금 더 밀어서 약간 위조했습니다.
Martin Ender

나는 당신의 imgur 연결이 끊어 졌다고 생각하고, 또한 나는 색깔과 모양을 즐기지 만, 나는 당신이 언급 한 이유 때문에 이것을 실격시켜야한다고 생각합니다.
alexander-brett

@ ali0sha 당신이 맞아요, 여기 고정 링크가 있습니다. 이 작품을 실격 처리하는 것은 절대적으로 공평합니다. 저는 Context Free Art를 일부 사람들과 공유하고 싶었습니다. ;) ... 그럼 난 여전히 ^^ 매스 매 티카 답을 가지고있다
마틴 청산

4

포스트 스크립트, 322 270

편집 :realtime 적절한 임의 생성기 시드로 사용할 수없는 것으로 보입니다 . 따라서이 목적으로 환경 변수를 사용하고 다음과 같이 프로그램을 실행합니다.

gs -c 20 $RANDOM -f tree.ps

또는

gswin32c -c 20 %RANDOM% -f tree.ps

이제 우리 나무는 예측하기 어렵습니다. 총 개수에 14 바이트가 추가됩니다. 기타 변경 사항 : 1) 이제 프로그램 인수가 명령 행에 전달됩니다. 2) 명시 적 반복 카운터가 없음-스택 크기가이 목적에 사용됩니다 (왼쪽 분기 회전 각도는 스택에 저장되어 나중에 오른쪽 분기를 그립니다). 3) 필요한 깊이에 대한 명명 된 변수가 없습니다-스택 크기는 스택의 오프셋입니다. 출구에 그대로 남아 있습니다. 즉 소비되지 않습니다.

srand
250 99 translate
50 50 scale
/f{
    count
    dup index div dup 1 le{
        0 exch 0 setrgbcolor
        0 0 1 1 rectfill
        0 1 translate
        rand 5 mod 1 add 15 mul
        gsave
        dup rotate
        dup cos dup scale
        f
        grestore
        dup cos dup dup mul
        exch 2 index sin mul translate
        dup 90 sub rotate
        sin dup scale 1
        f
        pop
    }{pop}ifelse
}def
f

그래픽 상태가 준비되고 f'왼쪽'과 '오른쪽'분기에 대해 연속적인 각 깊이 수준에 대해 두 번 재귀 적으로 호출됩니다. 1x1크기 가 직사각형 (원래 스케일 참조)으로 작업하면 측면 길이를 곱하는 문제가 해결됩니다. 왼쪽 가지의 회전 각도가 무작위입니다-5 개의 동일한 간격으로 구분 된 분할 중 하나가 사용됩니다-균일 한 무작위성에 대한 추악한 경우를 방지한다고 생각합니다.

필요한 깊이가 20 이상이면 느려질 수 있습니다.

다음은 ASCII 인코딩 바이너리 토큰을 사용하는 골프 버전입니다 (링크 된 주제의 luser droog의 답변 참조). 주, cos, sin, rand이 표기법을 사용할 수 없습니다.

/${{<920>dup 1 4 3 roll put cvx exec}forall}def srand 250 99<AD>$ 50 50<8B>$/f{count(8X68)$ 1 le{0(>)$ 0<9D>$ 0 0 1 1<80>$ 0 1<AD>$ rand 5 mod 1 add 15<~CecsG2u~>$ cos<388B>$ f(M8)$ cos(88l>)$ 2(X)$ sin<6CAD38>$ 90<A988>$ sin<388B>$ 1 f pop}{pop}(U)$}def f

.

/${{<920>dup 1 4 3 roll put cvx exec}forall}def
srand
250 99<AD>$
50 50<8B>$
/f{
count(8X68)$
1 le{
0(>)$ 0<9D>$
0 0 1 1<80>$
0 1<AD>$
rand 5 mod 1 add 15 
<~CecsG2u~>$
cos<388B>$ 
f
(M8)$
cos(88l>)$
2(X)$ sin<6CAD38>$
90<A988>$ sin<388B>$
1
f
pop
}{pop}(U)$
}def
f

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


여기 스타일은 명령 줄 인수를 추가하여 344 점을 더해야한다고 생각합니다. 코드 골프 표준으로도 이것은 상당히 인상적입니다. 바이너리 토큰으로 얼마나 멀리 얻을 수 있습니까? 당신은 확실히 Mathematica에서 멀지 않습니다
alexander-brett

@ ali0sha -dGraphicsAlphaBits는 큰 사각형의 들쭉날쭉 한 가장자리를 방지하기 위해 앤티 앨리어스 출력에 대한 플래그이며 생략 할 수 있습니다 (예 : 환경 변수에서 '숨겨 짐 '). 어떤 사람들은이 깃발없이 그것을 더 좋아할 수도 있습니다 (나무 잎은 더 많은 '볼륨'을 얻습니다). 글쎄, 그 20 바이트는별로 중요하지 않습니다. 나는 ASCII로 인코딩 된 바이너리 토큰을 사용하여 20-25 % 할인이라고 말합니다 (링크 된 주제 답변으로 판단). 시스템 이름 토큰 당 2 진 바이트 인 ASCII 인코딩없이 50 % 할인 될 수 있습니다. 일반적으로이기는 언어처럼 보일 것입니다.)
user2846289

나는 당신이 그것을해야한다고 생각합니다-여기에서 조금 더 경쟁적으로 만드십시오 :)
alexander-brett

3

커피 스크립트 377B 352B

나는 커피 스크립트를 작성하는 것이 더럽다고 생각하지만 python3에 대한 괜찮은 그림 패키지를 찾을 수 없습니다 :-/

Q=(n)->X=(D=document).body.appendChild(C=D.createElement('Canvas')).getContext('2d');C.width=C.height=400;M=Math;T=[[175,400,50,i=0]];S=M.sin;C=M.cos;while [x,y,l,a]=T[i++]
 X.save();X.translate x,y;X.rotate -a;X.fillRect 0,-l,l,l;X.restore();T.push [e=x-l*S(a),f=y-l*C(a),g=l*C(b=M.random()*M.PI/2),d=a+b],[e+g*C(d),f-g*S(d),l*S(b),d-M.PI/2] if i<2**n

자바 스크립트 393B 385B

자바 스크립트에서 약간 더 예쁘고 for-loop가 훨씬 행복하지만 [x, y, z] = A 구문이 없으면 커피 스크립트를 이길만큼 짧게 만들 수 없습니다.

function Q(n){X=(D=document).body.appendChild(C=D.createElement('Canvas')).getContext('2d');C.width=C.height=600;M=Math;T=[[275,400,50,i=0]];while(A=T[i++]){X.save();X.translate(x=A[0],y=A[1]);X.rotate(-(a=A[3]));X.fillRect(0,-(l=A[2]),l,l);X.restore();S=M.sin;C=M.cos;i<M.pow(2,n)&&T.push([e=x-l*S(a),f=y-l*C(a),g=l*C(b=M.random()*M.PI/2),d=a+b],[e+g*C(d),f-g*S(d),l*S(b),d-M.PI/2])}}

내가 조금 galled라고 말하면 이것은 수학 솔루션보다 거의 두 배나 길다 :-/ 실제로 그것을 보아라 : http://jsfiddle.net/FK2NX/3/


몇 가지 제안 : CoffeeScript에서 줄 바꿈 대신 세미콜론을 사용하여 16 자 이상을 저장할 수 있습니다. 두 경우 모두 Xreturn on 메소드 중 하나가 X있으면 연결할 수 있습니다. 그리고 단일 문자 변수를 저장 M.sin하고 저장하여 또 다른 좋은 문자를 저장할 M.cos수 있습니다.
Martin Ender

불행히도 컨텍스트 작업은 컨텍스트를 반환하지 않습니다. 또한 M.sin의 이름을 Ms로 바꿀 수 있지만 Ms = M.sin 줄은 저장하는 것보다 더 많은 문자를 사용합니다. 공백을 제거하는 방법을 살펴 보겠습니다.
alexander-brett

아니요, 할 수 있습니다 s=M.sin.
Martin Ender

어떻게 S = M.sin을 할 수 있지만 R = X.rotate는 할 수 없습니까?
alexander-brett

나는 가정 rotate사용을 this하고 sin있지 않습니다. 와 같은 작업을 수행해야 R=X.rotate.bind(X)하지만 더 이상 가치가 없을 것입니다.
Martin Ender
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.