Mi piacciono gli alberi di Pitagora


17

... quindi questa è una sfida per farmi un albero.

Produci un programma o una funzione chiamata albero che accetta un singolo argomento intero, N e disegna un albero pitagorico N livelli profondi, dove il livello 0 è solo il tronco.

Ogni giunzione dell'albero dovrebbe posizionare il vertice del triangolo in un punto casuale sul perimetro (questo punto dovrebbe essere distribuito uniformemente su almeno 5 punti equidistanti o uniformemente sull'intero semicerchio).

Opzionalmente il tuo albero può essere 3d, colorato o illuminato in base all'ora del giorno. Tuttavia, questo è code-golf, quindi vince il file più piccolo.

EDIT: chiuderò il concorso e accetterò la risposta più piccola quando è una settimana



Falso. Sto
cercando

Ok. Giusto. Potresti prendere in considerazione l'idea di ripetere il tuo invio a "Albero di Pitagora".
DavidC

Mi piacciono i treni? :)
tomsmeding,

Risposte:


15

Mathematica, 246 234 221 caratteri

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

Questo non è certamente il modo più elegante / breve per farlo.

Uso: f[8]

inserisci qui la descrizione dell'immagine

E qui ci sono esempi di output per f[6]e f[10]rispettivamente.

inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine

Abbastanza ungolfed:

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

È abbastanza impressionante. Peccato che non abbia matematica per testarlo - potresti aggiungere un altro paio di output di esempio?
alexander-brett,

@ ali0sha vedi modifica
Martin Ender il

Non è necessario Showlì, ed Moduleè anche inutile.
Swish

@swish Grazie per il Showsuggerimento, ma come posso liberarmene Module? Se non dichiaro plocale, verrà sovrascritto nelle chiamate ricorsive, quindi non potrei fare entrambe le chiamate con lo stesso p, giusto?
Martin Ender,

@ m.buettner Forse puoi usarlo Block, che è più corto di Module.
alephalpha,

20

CFDG, 134 caratteri

Questo non è esattamente valido, perché non è possibile limitare la profondità di ricorsione. Ma il problema richiede solo una soluzione in questo . :)

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

I risultati sembrano simili a questo

inserisci qui la descrizione dell'immagine

Per altri 46 caratteri ( 180 caratteri in totale), puoi persino colorarlo in:

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

inserisci qui la descrizione dell'immagine


So che questo non è completamente ontopico, ma come apparirebbe una versione se invece di "rumore bianco", usassi il "rumore marrone" come angoli?
ɐɔıʇǝɥʇuʎs

@Synthetica intendi con più angoli intorno a 90 ° e meno a 0 e 180?
Martin Ender,

@Synthetica Simile a questo . Non sono stato in grado di implementare il rumore di camminata casuale, perché ciò richiede prendere un parametro di input (l'ultimo valore casuale), regolarlo e trasmetterlo. Ciò renderebbe la grammatica sensibile al contesto e non è quindi supportata da CFDG. L'ho falsificato leggermente, semplicemente spingendo un po 'di più i valori casuali verso π / 2 usando una semplice funzione cubica sul campione casuale.
Martin Ender,

Penso che il tuo link imgur sia rotto, e anche se mi piacciono il colore e la forma, penso di dover squalificare questo per il motivo che hai menzionato
alexander-brett

@ ali0sha hai ragione, ecco il link fisso . Squalificare questo è assolutamente giusto, volevo solo condividere Context Free Art con alcune persone e mi è sembrato un approccio pulito al problema. ;) ... Beh, ho ancora la risposta di Mathematica ^^
Martin Ender,

4

Postscript, 322 270

Modifica: sembra che realtimenon possa essere usato come seme del generatore casuale corretto. Pertanto, utilizzeremo la variabile di ambiente per questo scopo ed eseguiremo il programma in questo modo:

gs -c 20 $RANDOM -f tree.ps

o

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

Ora i nostri alberi sono meno prevedibili. 14 byte vengono aggiunti al conteggio totale. Altre modifiche: 1) L'argomento del programma è ora passato alla riga di comando. 2) Nessun contatore di iterazioni esplicite - le dimensioni dello stack servono a questo scopo (l'angolo di rotazione del ramo sinistro viene memorizzato nello stack, per disegnare il ramo destro, in seguito). 3) Non esiste una variabile con nome per la profondità richiesta - la dimensione dello stack è il suo offset, sullo stack. Viene lasciato lì all'uscita, cioè non viene consumato.

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

Penso che sia abbastanza ovvio: lo stato della grafica è pronto e la fprocedura è chiamata ricorsivamente per ogni livello consecutivo di profondità, due volte, per i rami "sinistro" e "destro". Lavorare con un rettangolo di 1x1dimensioni (vedi scala originale) evita il problema di moltiplicare per la lunghezza laterale. L'angolo di rotazione del ramo sinistro è randomizzato - viene utilizzata una delle 5 divisioni casuali equidistanti - Penso che prevenga possibili casi brutti per casualità uniforme.

Potrebbe essere lento per una profondità richiesta di oltre 20 o giù di lì.

La prossima è la versione golf, usando i token binari con codifica ASCII (vedi la risposta del droog dell'utente dall'argomento collegato). Nota, cos, sin, randnon è possibile utilizzare questa notazione.

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

inserisci qui la descrizione dell'immagine


Penso che lo stile qui sia che gli argomenti della riga di comando devono essere aggiunti, quindi questo punteggio 344 ... Devo dire che anche per gli standard codegolf questo è piuttosto impressionante dall'aspetto straniero. Quanto lontano potresti arrivare con i token binari? Sicuramente non sei lontano da Mathematica
alexander-brett

@ ali0sha, -dGraphicsAlphaBitsè un flag di uscita anti-alias per impedire bordi frastagliati di quadrati più grandi, può essere omesso (o 'nascosto' ad es. in una variabile d'ambiente). Ad alcune persone potrebbe piacere di più senza questa bandiera (le foglie degli alberi ottengono più "volume"). Bene, quei 20 byte non sono molto importanti. Direi uno sconto del 20-25% usando i token binari con codifica ASCII (a giudicare dalla risposta dell'argomento collegato). Forse del 50% di sconto senza codifica ASCII, 2 byte binari per token nome di sistema.
Sembreranno

Penso che dovresti farlo -
rendilo

3

Coffeescript 377B 352B

Mi sento sporco scrivendo coffeescript ma non riesco a trovare un pacchetto di disegno decente per 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

Leggermente più carino in javascript e sono molto più felice con il for-loop ma senza la [x, y, z] = una sintassi che non riesco a rendere abbastanza breve da battere il 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])}}

Devo dire che sono un po 'irritato questo è quasi il doppio della soluzione matematica: - / vederlo in azione: http://jsfiddle.net/FK2NX/3/


Alcuni suggerimenti: è possibile salvare almeno 16 caratteri utilizzando i punti e virgola anziché le interruzioni di riga in CoffeeScript. In entrambi i casi, se uno qualsiasi dei metodi al Xritorno X, è possibile incatenarli. E puoi salvare un altro buon gruppo di caratteri salvando M.sine M.cosin variabili a carattere singolo.
Martin Ender,

Sfortunatamente le operazioni di contesto non restituiscono il contesto, cosa che mi ha fatto abbastanza arrabbiare. Inoltre, puoi rinominare M.sin in Ms, ma la riga Ms = M.sin occupa più caratteri di quanti ne risparmi ... Vedrò di eliminare gli spazi.
alexander-brett,

No, puoi semplicemente farlo s=M.sin.
Martin Ender,

Come mai posso fare S = M.sin, ma non R = X.rotate?
alexander-brett,

Suppongo che rotateusi thise sinnon. Dovresti fare qualcosa del genere R=X.rotate.bind(X), ma probabilmente non ne vale più la pena.
Martin Ender,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.