Pisagor ağaçlarını severim


17

... bu yüzden bu beni bir ağaç yapmak için bir meydan okuma.

Tek bir tamsayı bağımsız değişkeni olan N ve Pisagor Ağacı N düzeylerini derinden çizen, seviye 0'ın sadece gövde olduğu bir ağaç veya işlev üretin.

Ağacın her bir birleşimi, üçgenin tepe noktasını çevre üzerindeki rastgele bir noktaya yerleştirmelidir (bu nokta, en az 5 eşit aralıklı noktaya eşit olarak veya tüm yarım daire boyunca eşit olarak dağıtılmalıdır).

İsteğe bağlı olarak ağacınız 3B olabilir, renkli olabilir veya günün saatine göre aydınlatılabilir. Ancak, bu kod golf, bu yüzden en küçük dosya kazanır.

DÜZENLEME: Yarışmayı kapatacağım ve bir haftalık olduğunda en küçük cevabı kabul edeceğim



Yanlış. Farklı bir algoritmanın
peşindeyim

Tamam. Yeterince adil. "Pisagor Ağacı" na gönderiminizi yeniden düzenlemeyi düşünebilirsiniz.
DavidC

Trenleri severim? :)
tomsmeding

Yanıtlar:


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

Bu kesinlikle bunu yapmanın en zarif / en kısa yolu değildir.

Kullanımı: f[8]

resim açıklamasını buraya girin

Ve sırasıyla f[6]ve için örnek çıktılar f[10].

resim açıklamasını buraya girin resim açıklamasını buraya girin

Biraz soluksuz:

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

Bu oldukça etkileyici. Shame Test etmek için mathematica'm yok - birkaç örnek çıktı ekleyebilir misiniz?
alexander-brett

@ ali0sha bkz. düzenleme
Martin Ender

ShowOraya ihtiyacınız yok ve Moduleaynı zamanda gereksiz.
swish

@swish Showİpucu için teşekkürler , ama nasıl kurtulabilirim Module? pYerel olarak bildirmezsem , yinelemeli çağrılarda üzerine yazılır, bu yüzden her iki çağrıyı da aynı şekilde yapamadım p, değil mi?
Martin Ender 30'14

@ m.buettner Belki kullanabilirsiniz Block, ki bu daha kısadır Module.
alephalpha

20

CFDG, 134 karakter

Bu tam olarak geçerli değildir, çünkü özyineleme derinliğini sınırlayamazsınız. Ama sorun sadece bu konuda bir çözüm gerektiriyor . :)

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

Sonuçlar şuna benzer

resim açıklamasını buraya girin

46 karakter daha ( toplam 180 karakter ) için bile renklendirebilirsiniz:

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

resim açıklamasını buraya girin


Bunun tamamen ontopik olmadığını biliyorum, ama "beyaz gürültü" yerine bir versiyonun "kahverengi gürültü" yi açı olarak nasıl kullanırdınız?
Marıɐɔuʎs

@Synthetica, 90 ° civarında daha fazla açı ve 0 ve 180'de daha az açı ile mi demek istiyorsunuz?
Martin Ender

@Synthetica Buna benzer . Gerçek bir rastgele yürüyüş gürültüsü uygulayamadım, çünkü bu bir giriş parametresi (son rastgele değer) alarak, onu ayarlayıp geçirmeyi gerektirir. Bu, dilbilgisini içeriğe duyarlı hale getirir ve bu nedenle CFDG tarafından desteklenmez. Rastgele örnek üzerinde basit bir kübik fonksiyon kullanarak rastgele değerleri π / 2'ye doğru biraz daha iterek biraz taklit ettim.
Martin Ender

Ben imgur bağlantınızın bozuk olduğunu düşünüyorum, ve aynı zamanda renk ve şeklin tadını çıkarmasına rağmen, bahsettiğiniz nedenden dolayı bunu diskalifiye etmeliyim
alexander-brett

@ ali0sha haklısın, işte sabit bağlantı . Bunu diskalifiye etmek kesinlikle adil, sadece Bağlamsız Sanatı bazı insanlarla paylaşmak istedim ve sorun için düzgün bir yaklaşım gibi görünüyordu. ;) ... Eh hala Mathematica cevap var ^ ^
Martin Ender

4

Postscript, 322 270

Düzenleme: Görünüşe göre realtimeuygun rastgele jeneratör tohumu olarak kullanılamaz. Bu nedenle, ortam değişkenini bu amaçla kullanacağız ve programı şu şekilde çalıştıracağız:

gs -c 20 $RANDOM -f tree.ps

veya

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

Şimdi ağaçlarımız daha az tahmin edilebilir. Toplam sayıya 14 bayt eklenir. Diğer değişiklikler: 1) Program argümanı artık komut satırında iletildi. 2) Hiçbir açık yineleme karşı yığını boyutu bu amaca hizmet etmez (daha sonra sağ dalı çizmek için sol dal dönüş açısı yığın üzerinde saklanır). 3) Gerekli derinlik için adlandırılmış bir değişken yoktur - yığın boyutu, yığın üzerindeki ofsetidir. Orada çıkışta bırakılır, yani tüketilmez.

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

Oldukça açık olduğunu düşünüyorum - grafik durumu hazırlanıyor ve fprosedür 'ardışık her derinlik seviyesi için iki kez -' sol 've' sağ 'dallar için tekrar tekrar çağrılıyor. Dikdörtgeni ile çalışma1x1Boyut (orijinal ölçeğe bakın), yan uzunluk ile çarpma sorununu ortadan kaldırır. Sol dalın dönme açısı randomize edilir - 5 rastgele eşit aralıklı bölümden biri kullanılır - bence tekdüze rastgele olma için olası çirkin vakaları önler.

20 veya daha fazla gerekli derinlik için yavaş olabilir.

Sırada ASCII kodlu ikili jetonlar kullanan golf versiyonudur (bkz. Luser droog'un bağlantılı konudan cevabı). Not cos, sin, randbu notasyonu kullanamaz.

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

resim açıklamasını buraya girin


Buradaki stil, komut satırı argümanlarının eklenmesi gerektiğine inanıyor, bu yüzden bu puanlar 344 ... Codegolf standartlarına göre bile bu oldukça etkileyici görünüyor. İkili jetonlarla ne kadar ileri gidebilirsin? Kesinlikle Mathematica uzakta değilsiniz
alexander-brett

@ ali0sha, -dGraphicsAlphaBitsdaha büyük karelerin pürüzlü kenarlarını önlemek için kenar yumuşatma çıkışına bir bayraktır, atlanabilir (veya örneğin ortam değişkeninde 'gizlenebilir'). Bazı insanlar bu bayrak olmadan daha fazla sevebilirler (ağaç yaprakları daha fazla 'hacim' alır). Bu 20 bayt o kadar önemli değil. ASCII kodlu ikili jetonları kullanarak% 20-25 oranında kapalı olduğunu söyleyebilirim (bağlantılı konuya göre karar verir) Ascii kodlaması olmadan belki% 50 indirim, sistem adı belirteci başına 2 ikili bayt. Genellikle kazanan bazı diller gibi görünecektir;)
user2846289

Bence bunu yapmalısın - burada biraz daha rekabetçi hale
getir

3

Coffeescript 377B 352B

Ben kirli yazma kahve hissediyorum ama python3 için iyi bir çizim paketi bulamıyorum: - /

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 biraz daha güzel ve for-loop ile çok daha mutluyum ama olmadan [x, y, z] = Bir sözdizimi ben sadece kahve yenmek için yeterince kısa yapamam

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

Bu biraz matematiksel çözüm neredeyse iki kat daha uzun olduğunu söylemek gerekir: - / eylem görmek: http://jsfiddle.net/FK2NX/3/


Birkaç öneri: CoffeeScript'te satır kesmeleri yerine noktalı virgül kullanarak en az 16 karakter kaydedebilirsiniz. Her iki durumda da, Xiade edilen yöntemlerden herhangi biri Xvarsa, bunları zincirleyebilirsiniz. Ve tek karakterli değişkenleri kaydederek M.sinve başka bir iyi karakter grubunu kaydedebilirsiniz M.cos.
Martin Ender

Ne yazık ki bağlam işlemleri, oldukça üzdüğüm bağlamı döndürmüyor. Ayrıca, M.sin'i Ms olarak yeniden adlandırabilirsiniz, ancak Ms = M.sin satırı kaydettiğinden daha fazla karakter alır ... Boşlukları soymaya bakacağım.
alexander-brett

Hayır, sadece yapabilirsiniz s=M.sin.
Martin Ender

Neden S = M.sin yapabilirim ama R = X.rotate yapamıyorum?
alexander-brett

Sanırım rotatekullanımları var thisve sindeğil. Bunun gibi bir şey yapmanız gerekir R=X.rotate.bind(X), ama muhtemelen buna artık değmez.
Martin Ender
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.