ピタゴラスの木が好き


17

...だからこれは私を木にする挑戦です。

単一の整数引数Nを取り、Nレベルのピタゴラスツリーを描画するtreeと呼ばれるプログラムまたは関数を作成します。レベル0はトランクのみです。

ツリーの各ジャンクションは、周囲のランダムなポイントに三角形の頂点を配置する必要があります(このポイントは、少なくとも5つの等間隔のポイント、または半円全体に均等に分散する必要があります)。

必要に応じて、時刻に応じてツリーを3Dにしたり、カラフルにしたり、点灯させたりできます。ただし、これはコードゴルフなので、最小のファイルが優先されます。

編集:コンテストを終了し、1週間経過したら最小の回答を受け入れます


重複して表示されます。codegolf.stackexchange.com/questions/18785/...
DavidC

偽。私は別のアルゴリズムを
求めてい

OK。けっこうだ。「ピタゴラスの木」への投稿のタイトルを変更することを検討してください。
DavidC 14年

私は電車が好きです?:)
tomsmeding 14

回答:


15

Mathematica、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[#] &

それは非常に印象的です。恥ずかしい私はそれをテストするための数学を持っていません-いくつかの出力例を追加できますか?
アレクサンダー・ブレット14年

@ ali0sha編集を参照
マーティンエンダー14年

あなたはShowそこにいる必要はなく、Moduleまた不必要です。
スウィッシュ

@swish Showヒントをありがとう、しかしどうすれば取り除くことができModuleますか?plocalを宣言しないと、再帰呼び出しで上書きされるため、同じ呼び出しで両方の呼び出しを行うことはできませんでしたpか?
マーティンエンダー14年

m.buettner @たぶん、あなたは使用することができますBlockよりも短くなっています、Module
alephalpha 14年

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°前後のより多くの角度を意味しますか?
マーティンエンダー14年

@Synthetica これに似ています。実際のランダムウォークノイズを実装できませんでした。入力パラメータ(最後のランダム値)を取得し、調整して渡す必要があるためです。これにより、文法が文脈依存になり、CFDGでサポートされなくなります。ランダムサンプルで単純な3次関数を使用して、ランダム値をπ/ 2の方に少しだけプッシュすることで、少し偽造しました。
マーティンエンダー14年

私はあなたのimgurリンクが壊れていると思いますし、私は色や形を楽しむことも非常にかかわらず、私はあなたが言及した理由でこの1を失格しなければならないと思います
アレクサンダー・ブレット

あなたが正しい@ ali0sha、ここに固定リンクがあります。これを完全に失格にすることは絶対に公正であり、Context Free Artを一部の人々と共有したかっただけで、問題に対するきちんとしたアプローチのように思えました。;)...まあ私はまだMathematicaの答えを持っています^^
Martin Ender 14

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プロシージャがそれぞれの連続する深さレベルで2回再帰的に呼び出されます-「左」と「右」の分岐に対して。1x1サイズの長方形(元のスケールを参照)を使用すると、辺の長さを掛ける手間が省けます。左枝の回転角度はランダム化されます-5つのランダムな等間隔の分割の1つが使用されます-均一なランダム性のpossibleいケースを防ぐことができると思います。

必要な深さが20を超えると、処理が遅くなる場合があります。

次は、ASCIIエンコードバイナリトークンを使用したゴルフバージョンです(リンクされたトピックからのluser droogの回答を参照)。注、cossinrandこの表記を使用することはできません。

/${{<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オフじゃない
アレクサンダー・ブレット

@ ali0sha -dGraphicsAlphaBitsは、より大きな正方形のギザギザのエッジを防ぐためのアンチエイリアス出力のフラグです。これは省略できます(または環境変数では「非表示」)。一部の人々は、このフラグなしでそれをより好むかもしれません(木の葉はより多くの「ボリューム」を取得します)。さて、これらの20バイトはそれほど重要ではありません。アスキーエンコードされたバイナリトークンを使用すると20-25%オフになります(リンクされたトピックの回答から判断)。ascii-encodingなしで50%オフになる可能性があります。システム名トークンごとに2バイナリバイト。いくつかの通常勝つ言語のように見えます;)
user2846289 14

私はあなたがそれをやるべきだと思う-ここで少し競争力を
高める

3

Coffeescript 377B 352B

coffeescriptを書くのは汚い気がしますが、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

Javascript 393B 385B

javascriptが少しきれいで、for-loopの方がはるかに幸せですが、[x、y、z] = A構文がないので、coffeescriptに勝るほど短くすることはできません。

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

私は少し悩んでいると言ってしまいましたが、これは数学ソリューションのほぼ2倍の長さです:-/実際にそれを見る:http : //jsfiddle.net/FK2NX/3/


いくつかの提案:CoffeeScriptで改行の代わりにセミコロンを使用すると、少なくとも16文字を保存できます。どちらの場合でも、X戻り時Xにメソッドのいずれかがあれば、それらを連鎖させることができます。そして、あなたは保存することで、文字の別の良い束を保存することができますM.sinし、M.cos単一の文字変数に。
マーティンエンダー14

残念ながら、コンテキスト操作はコンテキストを返しません。また、M.sinの名前をMsに変更することもできますが、Ms = M.sinの行は保存するよりも多くの文字を使用します...スペースを削除する方法を見ていきます。
アレクサンダー・ブレット14

いいえ、できますs=M.sin
マーティンエンダー14

R = X.rotateではなく、S = M.sinを実行できるのはなぜですか?
アレクサンダーブレット14

rotate使用しthis、使用sinしないと思います。のようなことをする必要がありますがR=X.rotate.bind(X)、おそらくそれ以上の価値はありません。
マーティンエンダー14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.