Frattale di albero binario


25

La sfida di oggi è disegnare un albero binario come una bella come questo esempio:

                               /\
                              /  \
                             /    \
                            /      \
                           /        \
                          /          \
                         /            \
                        /              \
                       /                \
                      /                  \
                     /                    \
                    /                      \
                   /                        \
                  /                          \
                 /                            \
                /                              \
               /\                              /\
              /  \                            /  \
             /    \                          /    \
            /      \                        /      \
           /        \                      /        \
          /          \                    /          \
         /            \                  /            \
        /              \                /              \
       /\              /\              /\              /\
      /  \            /  \            /  \            /  \
     /    \          /    \          /    \          /    \
    /      \        /      \        /      \        /      \
   /\      /\      /\      /\      /\      /\      /\      /\
  /  \    /  \    /  \    /  \    /  \    /  \    /  \    /  \
 /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

Ti verrà dato un numero intero positivo come input. Questo input è l' altezza dell'albero . L'esempio sopra ha un'altezza di sei.

Puoi inviare un programma completo o una funzione e sei libero di utilizzare uno qualsiasi dei nostri metodi IO predefiniti . Ad esempio, sarebbe consentito stampare l'albero, restituire una stringa con newline, restituire un array di caratteri 2D, salvare l'albero in un file, ecc.

Sono consentiti spazi finali su ciascuna riga.

Ecco alcuni esempi di ingressi e delle relative uscite:

1:
/\

2:
 /\
/\/\

3:
   /\
  /  \
 /\  /\
/\/\/\/\

4:
       /\
      /  \
     /    \
    /      \
   /\      /\
  /  \    /  \
 /\  /\  /\  /\
/\/\/\/\/\/\/\/\

5:
               /\
              /  \
             /    \
            /      \
           /        \
          /          \
         /            \
        /              \
       /\              /\
      /  \            /  \
     /    \          /    \
    /      \        /      \
   /\      /\      /\      /\
  /  \    /  \    /  \    /  \
 /\  /\  /\  /\  /\  /\  /\  /\
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

Sfortunatamente, l'output cresce esponenzialmente, quindi è difficile mostrare esempi più grandi. Ecco un link all'output per 8.

Come al solito, si tratta di una sfida al , quindi si applicano scappatoie standard e provate a scrivere il programma più breve possibile in qualunque lingua scegliate.

Buon golf!


Possono esserci spazi finali per rendere tutte le linee della stessa lunghezza?
xnor

@xnor Sì, va bene.
DJMcMayhem

Risposte:


5

Python 2, 77 byte

S=s=i=2**input()
while s:print S/s*('/'+' '*(s-i)+'\\').center(s);i-=2;s/=s/i

Stampa con spazi finali, terminando con errori.

Ho preso questo codice dalla mia presentazione a una sfida che ho posto su Anarchy Golf , oltre a un miglioramento di un byte trovato da xsot. Il valore hardcoded di 128 è stato modificato in 2**input().

L'idea è che ogni riga dell'output sia un segmento copiato una o più volte. La metà dopo la divisione di input ha una copia di ogni segmento, il quarto dopo la divisione successiva ha due copie e così via, fino all'ultima riga con molti segmenti di /\.

Ogni segmento aveva un /e \, con spazi in mezzo, così come all'esterno per riempire alla giusta lunghezza. L'imbottitura esterna è terminata center.

La variabile stiene traccia della corrente con di ciascun segmento e il numero di segmenti è S/stale che la larghezza totale è la larghezza dell'albero S. Il numero di riga iconta alla rovescia di 2 e ogni volta che il valore ne srappresenta la metà, si verifica una divisione e la larghezza del segmento si dimezza. Questo viene fatto tramite l'espressione s/=s/i. Quando iraggiunge 0, questo dà un errore che termina il programma.

Poiché anagolf consente solo l'invio di programmi, non ho esplorato la possibilità di una funzione ricorsiva, che penso sia probabilmente più breve.


4

V , 32 byte

é\é/À­ñLyPÄlx$X>>îò^llÄlxxbPò
|

Provalo online!

hexdump:

00000000: e95c e92f c0ad f116 4c79 50c4 6c78 2458  .\./....LyP.lx$X
00000010: 3e3e eef2 5e6c 6cc4 6c78 7862 50f2 0a7c  >>..^ll.lxxbP..|

4

Tela , 11 byte

/║╶╷[l\;∔↔║

Provalo qui!

Spiegazione:

/║          push `/\` ("/" palindromized so this is a Canvas object)
  ╶╷[       repeat input-1 times
     l        get the width of the ToS
      \       create a diagonal that long
       ;∔     prepend that to the item below
         ↔    reverse the thing horizontally
          ║   and palindromize it horizontally

3

Haskell , 140 138 135 byte

e n=[1..n]>>" "
n!f=(e n++).(++e n)<$>f
f 0=[]
f n=1!f(n-1)++['/':e(2*n-2)++"\\"]
b n|n<2=f 1|t<-b$n-1,m<-2^(n-2)=m!f m++zipWith(++)t t

Provalo online! Chiama con b 5, restituisce un elenco di stringhe.

Abbastanza utilizzo di stampa:

*Main> putStr . unlines $ b 5
               /\
              /  \
             /    \
            /      \
           /        \
          /          \
         /            \
        /              \
       /\              /\
      /  \            /  \
     /    \          /    \
    /      \        /      \
   /\      /\      /\      /\
  /  \    /  \    /  \    /  \
 /\  /\  /\  /\  /\  /\  /\  /\
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

(alcuni) Spiegazione:

  • e n genera una stringa di n spazi
  • n!friempie ogni stringa nell'elenco di stringhe fcon nspazi a sinistra e a destra
  • f ndisegna un "picco" in un nby 2nrettangolo di
  • b n disegna l'albero binario concatenando due alberi più piccoli e centra un nuovo picco sopra di essi

Modifica: -3 byte grazie a Zgarb!


Penso 1!f(n-1)e m!f mdovrei salvare un paio di byte.
Zgarb,

@Zgarb Grazie per aver sottolineato, quelle regole di precedenza a volte diventano confuse.
Laikoni,

2

J , 49 43 42 byte

' /\'{~(|.,-)"1@(=@i.@#,-)^:(<:`(,:@,&*-))

Questo restituisce un verbo che accetta un numero e restituisce una matrice di caratteri 2D. Provalo online!

Spiegazione

Prima costruisco una matrice dei valori -1, 0 e 1 ripetendo un verbo ausiliario, quindi sostituisco i numeri con caratteri. Il verbo ausiliario costruisce la metà destra dell'iterazione successiva, quindi la riflette in orizzontale per produrre il resto. Nella seguente spiegazione, ,concatena le matrici 2D in verticale e le matrici 1D in orizzontale.

' /\'{~(|.,-)"1@(=@i.@#,-)^:(<:`(,:@,&*-))  Input is n.
                          ^:(            )  Iterate this verb
                             <:             n-1 times
                               `(       )   starting from
                                    ,&*-    the array 1 -1 (actually sign(n), sign(-n))
                                 ,:@        shaped into a 1x2 matrix:
                                             Previous iteration is y.
                      #                      Take height of y,
                   i.@                       turn into range
                 =@                          and form array of self-equality.
                                             This results in the identity
                                             matrix with same height as y.
                       ,-                    Concatenate with -y, pad with 0s.
       (    )"1@(        )                   Then do to every row:
        |.,-                                 Concatenate reversal to negation.
' /\'{~                                     Finally index entry-wise into string.

1

JavaScript (ES6), 105 byte

f=n=>n<2?"/\\":" "+f(n-1).split`/`[0].replace(/|/g,"$`$'$'/$`$`\\$'$'$` \n")+f(n-1).replace(/.*/g,"$&$&")

Funziona costruendo il risultato in modo ricorsivo dal case base/\ . La metà inferiore è solo il caso precedente con ogni riga duplicata. La metà superiore era un po 'più complicata; sembra che tu voglia prendere il caso precedente e mantenere solo i due lati, ma devi anche preoccuparti di riempire le corde per raddoppiare la larghezza, quindi invece faccio un po 'di magia regex. Prendendo gli spazi iniziali dal caso precedente e suddividendoli in ogni punto, posso considerare gli spazi prima e dopo quel punto. Ad ogni corrispondenza gli spazi prima aumentano di 1 e gli spazi dopo diminuiscono di 1; questo può essere usato per posizionare /e\nei posti corretti. Le newline e le imbottiture sono anche aggiunte qui; questo si occupa di tutte le imbottiture tranne uno spazio finale su ogni riga e uno spazio iniziale sulla prima riga che devo aggiungere manualmente. (Gli spazi iniziali sulle righe successive provengono dalla stringa corrispondente).


1

Carbone , 12 byte

FN«→↗⌈X²⊖ι‖M

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

 N              Input as a number
F «             Loop over implicit range
   →            Move right (because mirroring moves the cursor)
         ι      Current index
        ⊖       Decremented
      X²        Power of 2
     ⌈          Ceiling
    ↗           Draw diagonal line
          ‖M    Mirror image

Le lunghezze delle linee sono 1, 1, 2, 4, 8 ... 2 ^ (N-2), quindi il calcolo scomodo.



0

Lotto, 218 byte

@echo off
set/a"n=1<<%1"
set s=set t=
%s%/\
set l=for /l %%i in (2,1,%n%)do call
%l% %s% %%t%% 
%l%:l
:l
echo %t%
set/an-=1,m=n^&n-1
%s%%t: /=/ %
%s%%t:\ = \%
if %m% neq 0 exit/b
%s%%t:/ =/\%
%s%%t: \=/\%

Nota: la riga 6 termina in uno spazio. Funziona spostando i rami a sinistra e a destra in modo appropriato ogni volta, ad eccezione delle file che sono 2 n dalla fine, nel qual caso i rami vengono invece biforcati.


0

Haxe, 181 byte

function g(n):String return(n-=2)==-1?"/\\":[for(y in 0...1<<n)[for(x in 0...4<<n)x+y+1==2<<n?"/":x-y==2<<n?"\\":" "].join("")].concat([for(y in g(n+1).split("\n"))y+y]).join("\n");

Oppure, con alcuni spazi bianchi opzionali:

function g(n):String
  return
    (n -= 2) == -1
    ? "/\\"
    : [ for (y in 0...1 << n)
        [ for (x in 0...4 << n)
          x + y + 1 == 2 << n
          ? "/"
          : x - y == 2 << n
            ? "\\"
            : " "
        ].join("")
      ].concat([ for (y in g(n + 1).split("\n"))
        y + y
      ]).join("\n");

Ho lavorato per un po 'su una soluzione che ha creato prima una serie di caratteri spaziali della giusta dimensione, quindi ha ripetutamente messo i percorsi biforcuti sempre più in basso (e più densamente ad ogni iterazione). Rimanevano 230+ byte, però. L'approccio qui è praticamente quello che è l'approccio Haskell di @ Laikoni. Non riuscivo a :Stringcavarmela senza averlo fatto , perché Haxe non è abbastanza intelligente da identificare che il tipo restituito sarà sempre una stringa.

Questa è solo una funzione, ecco un programma completo per testarlo:

class Main {
    public static function main(){
        function g(n):String return(n-=2)==-1?"/\\":[for(y in 0...1<<n)[for(x in 0...4<<n)x+y+1==2<<n?"/":x-y==2<<n?"\\":" "].join("")].concat([for(y in g(n+1).split("\n"))y+y]).join("\n");
        Sys.println(g(Std.parseInt(Sys.args()[0])));
    }
}

Inserire quanto sopra Main.hx, compilare haxe -main Main.hx -neko frac.ne testare con neko frac.n 4(sostituire 4con l'ordine desiderato).


0

PHP, 188 byte

Versione online

function f($l,$r=0,$m=1){global$a;for(;$i<$l;$i++)$i<$l/2?$a[$i+$r]=str_repeat(str_pad("/".str_pad("",2*$i)."\\",2*$l," ",2),$m):f($l/2^0,$r+$l/2,2*$m);}f(2**$argv[1]/2);echo join("\n",$a);

allargato

function f($l,$r=0,$m=1){
global$a;    
for(;$i<$l;$i++)    
$i<$l/2
    ?$a[$i+$r]=str_repeat(str_pad("/".str_pad("",2*$i)."\\",2*$l," ",2),$m)
    :f($l/2^0,$r+$l/2,2*$m);
}
f(2**$argv[1]/2);
echo join("\n",$a);
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.