Saya suka pohon Pythagoras

17

... jadi ini adalah tantangan untuk menjadikanku pohon.

Menghasilkan program atau fungsi yang disebut tree yang mengambil argumen integer tunggal, N dan menggambar level Pythagoras Tree N dalam, di mana level 0 hanya trunk.

Setiap persimpangan pohon harus menempatkan simpul segitiga pada titik acak pada perimeter (titik ini harus terdistribusi secara merata di setidaknya 5 titik yang sama jaraknya, atau seragam di seluruh setengah lingkaran).

Opsional pohon Anda mungkin 3d, berwarna-warni, atau menyala sesuai waktu. Namun, ini adalah kode-golf, jadi file terkecil menang.

EDIT: Saya akan menutup kontes dan menerima jawaban terkecil saat berumur seminggu

alexander-brett
sumber
Tampak sebagai duplikat: codegolf.stackexchange.com/questions/18785/…
DavidC
Salah. Saya mengejar algoritma yang berbeda :)
alexander-brett
Baik. Cukup adil. Anda mungkin ingin mempertimbangkan untuk membalas kiriman Anda ke "Pohon Pythagoras".
DavidC
Saya suka kereta? :)
tommeding

Jawaban:

15

Mathematica, 246 234 221 karakter

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@#&

Ini tentu bukan cara yang paling elegan / terpendek untuk melakukan ini.

Pemakaian: f[8]

masukkan deskripsi gambar di sini

Dan berikut adalah contoh output untuk f[6]dan f[10]masing - masing.

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

Agak tidak terserang:

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[#] &
Martin Ender
sumber
Itu cukup mengesankan. Sayang sekali saya tidak memiliki mathatica untuk mengujinya - dapatkah Anda menambahkan beberapa contoh output?
alexander-brett
@ ali0sha lihat sunting
Martin Ender
Anda tidak perlu Showdi sana, dan Modulejuga tidak perlu.
desir
@berharap Terima kasih atas Showpetunjuknya, tetapi bagaimana saya bisa menyingkirkannya Module? Jika saya tidak mendeklarasikan plokal, itu akan ditimpa dalam panggilan rekursif, jadi saya tidak bisa melakukan keduanya dengan yang sama p, kan?
Martin Ender
@ m.buettner Mungkin Anda bisa menggunakan Block, yang lebih pendek dari Module.
alephalpha
20

CFDG, 134 karakter

Yang ini tidak persis benar, karena Anda tidak dapat membatasi kedalaman rekursi. Tetapi masalahnya hanya membutuhkan solusi dalam hal ini . :)

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

Hasilnya terlihat seperti ini

masukkan deskripsi gambar di sini

Untuk 46 karakter lainnya ( total 180 karakter ), Anda dapat mewarnai:

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

masukkan deskripsi gambar di sini

Martin Ender
sumber
Saya tahu ini bukan sepenuhnya ontopic, tetapi bagaimana versi terlihat jika alih-alih "white noise", Anda menggunakan "brown noise" sebagai sudut?
ɐɔıʇǝɥʇuʎs
@ Sintetica yang Anda maksud dengan lebih banyak sudut di sekitar 90 ° dan kurang pada 0 dan 180?
Martin Ender
@ Sintetica Mirip dengan ini . Saya tidak dapat mengimplementasikan suara berjalan acak yang sebenarnya, karena itu membutuhkan pengambilan parameter input (nilai acak terakhir), menyesuaikannya dan meneruskannya. Ini akan membuat konteks tata bahasa menjadi sensitif dan karenanya tidak didukung oleh CFDG. Saya sedikit memalsukannya, dengan hanya mendorong nilai acak sedikit lebih ke arah π / 2 menggunakan fungsi kubik sederhana pada sampel acak.
Martin Ender
Saya pikir tautan imgur Anda rusak, dan meskipun saya menikmati warna dan bentuknya, saya pikir saya harus mendiskualifikasi yang ini karena alasan yang Anda sebutkan
alexander-brett
@ ali0sha Anda benar, ini tautannya . Mendiskualifikasi yang ini benar-benar adil, saya hanya ingin berbagi Context Free Art dengan beberapa orang dan sepertinya pendekatan yang rapi untuk masalah ini. ;) ... Yah saya masih punya jawaban Mathematica ^^
Martin Ender
4

Catatan tambahan, 322 270

Sunting: Tampaknya realtimetidak dapat digunakan sebagai seed generator acak yang tepat. Karenanya, kami akan menggunakan variabel lingkungan untuk tujuan ini dan menjalankan program seperti itu:

gs -c 20 $RANDOM -f tree.ps

atau

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

Sekarang pohon kita kurang dapat diprediksi. 14 byte ditambahkan ke jumlah total. Perubahan lain: 1) Argumen program sekarang diteruskan pada baris perintah. 2) Tidak ada ukuran counter - stack iterasi eksplisit yang berfungsi untuk tujuan ini (sudut rotasi cabang kiri disimpan pada stack, untuk menggambar cabang kanan, nanti). 3) Tidak ada variabel bernama untuk kedalaman yang diperlukan - ukuran stack adalah offsetnya, pada stack. Ditinggalkan di sana saat keluar, artinya tidak dikonsumsi.

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

Saya pikir itu cukup jelas - keadaan grafis disiapkan dan fprosedur disebut secara rekursif untuk setiap tingkat kedalaman berturut-turut, dua kali - untuk cabang 'kiri' dan 'kanan'. Bekerja dengan 1x1ukuran persegi panjang (lihat skala asli) menghemat kesulitan mengalikan dengan panjang sisi. Sudut rotasi cabang kiri diacak - salah satu dari 5 pembagian acak yang berjarak sama - saya pikir itu mencegah kemungkinan kasus jelek untuk keseragaman yang seragam.

Mungkin lambat untuk kedalaman yang dibutuhkan lebih dari 20 atau lebih.

Berikutnya adalah versi golf, menggunakan token biner berkode ASCII (lihat jawaban luser droog dari topik tertaut). Catatan, cos, sin, randtidak dapat menggunakan notasi ini.

/${{<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

masukkan deskripsi gambar di sini

pengguna2846289
sumber
Saya pikir gaya di sini adalah bahwa argumen baris perintah perlu ditambahkan sehingga ini skor 344 ... Saya harus mengatakan bahwa bahkan oleh standar codegolf ini cukup mengesankan tampak asing. Seberapa jauh Anda bisa mendapatkannya dengan token biner? Anda tidak jauh dari Mathematica
alexander-brett
@ ali0sha, -dGraphicsAlphaBitsadalah flag ke keluaran anti-alias untuk mencegah tepi bergerigi dari kotak yang lebih besar, dapat dihilangkan (atau 'disembunyikan' dalam misalnya variabel lingkungan). Beberapa orang mungkin lebih menyukainya tanpa bendera ini (daun pohon mendapatkan lebih banyak 'volume'). Ya, 20 byte itu tidak terlalu penting. Saya akan mengatakan 20-25% off menggunakan token biner berkode ascii (dilihat dari jawaban topik terkait). Mungkin diskon 50% tanpa pengkodean ascii, 2 byte biner per token nama sistem. Akan terlihat seperti beberapa bahasa yang biasanya menang;)
user2846289
Saya pikir Anda harus melakukannya - membuatnya sedikit lebih kompetitif di sini :)
alexander-brett
3

Coffeescript 377B 352B

Saya merasa kotor menulis coffeescript tetapi saya tidak dapat menemukan paket gambar yang layak untuk 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

Agak cantik dalam javascript dan saya jauh lebih bahagia dengan for-loop tetapi tanpa [x, y, z] = Sintaksis saya tidak bisa membuatnya cukup pendek untuk mengalahkan naskah kopi

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

Saya harus mengatakan bahwa saya agak kesal ini hampir dua kali lebih lama dari solusi Mathematica: - / Saya melihatnya dalam aksi: http://jsfiddle.net/FK2NX/3/

alexander-brett
sumber
Beberapa saran: Anda dapat menyimpan setidaknya 16 karakter dengan menggunakan titik koma alih-alih jeda baris dalam CoffeeScript. Dalam kedua kasus, jika ada salah satu metode Xpengembalian X, Anda dapat rantai mereka. Dan Anda dapat menyimpan banyak karakter lain dengan menyimpan M.sindan M.cosdalam variabel karakter tunggal.
Martin Ender
Sayangnya operasi konteks tidak mengembalikan konteks, yang saya cukup kesal. Juga, Anda dapat mengubah nama M.sin menjadi Ms, tetapi baris Ms = M.sin membutuhkan lebih banyak karakter daripada menghemat ... Saya akan melihat cara menghapus spasi.
alexander-brett
Tidak, Anda bisa melakukannya s=M.sin.
Martin Ender
Kenapa saya bisa melakukan S = M.sin, tetapi tidak R = X.rotate?
alexander-brett
Saya kira rotatemenggunakan this, dan sintidak. Anda perlu melakukan sesuatu seperti R=X.rotate.bind(X), tetapi itu mungkin tidak sepadan lagi.
Martin Ender