Esagoni incorporati!


18

Il tuo compito: dato un numero intero n, genera un modello esagonale incorporato seguendo le regole seguenti, all'ennesima profondità.

Un esagono incorporato ha la forma base di questo: ( n=0)

 __      
/  \
\__/

Esagoni incorporati n=1e n=2:

  ____    
 /  \ \
/\__/  \
\      /
 \____/

    ________    
   /  \ \   \
  /\__/  \   \
 /\      /    \
/  \____/      \
\              /
 \            /
  \          /
   \________/

La lunghezza di ciascun lato è 2 volte la lunghezza dello stesso lato nelle profondità precedenti due volte. I lati superiore e inferiore sono lunghi 2 caratteri quando n=0e il resto inizia come 1 carattere. Le lunghezze dei lati non superiori devono essere 2^nlunghe ( OEIS: A000079 ) e i lati superiore e inferiore devono seguire la regola 2^(n+1)(stesso OEIS).

Gli esagoni attuali sono indicizzati 0, puoi scegliere di usare 1 indicizzato se vuoi.

Questo è , quindi vince la risposta più breve!


@LuisMendo Va bene, cambierò il nome.
Compagno SparklePony

Potrebbe essere difficile gestire input di grandi dimensioni (es. 64). C'è un limite a n?
Matthew Roh,

@SIGSEGV Non c'è limite a n.
Compagno SparklePony

1
Sarebbe divertente vedere una risposta in Esagonia :))
Mr. Xcoder

1
Heh, anche la grafica delle tartarughe della mia presentazione della curva di Koch può fare questo (solo la prima funzione è cambiata). Sicuramente troppo a lungo per questo, però :)
Ørjan Johansen

Risposte:


10

Carbone , 40 29 byte

11 byte salvati grazie a @Neil modificando il ciclo while in un ciclo for tra gli altri trucchi

FN«AX²ιβ×__β↓↘β←↙β↑←×__β↖β→↗β

Provalo online!

Spiegazione (obsoleta)

Questo programma inizia con la generazione dell'esagono più grande, quindi esegue uno per uno i più piccoli in un ciclo while (1 indicizzato). Per riferimento, αè il numero di input, βè la variabile che contiene 2^(α-1)ed ιè la variabile iterante nel ciclo.

Nα                        # Take input and store in α
Wα«                       # While α do:
 ×_X²ι                    #  Write "_"*(2**ι); this forms the top edge of the hexagon
 ↓                         #  Go down
 AX²⁻ι¹β                 #  Assign 2**(ι-1) to β
 ↘β←                       #  Write \ β times in a SE direction (top right edge) and then go left
 ↙β↑                       #  Write / β times in a SW direction (bottom right edge) and then go up
 ←×_X²ι                   #  Write the bottom edge
 ↖β→↗β                    #  Just like before, write the top and bottom left edges
 A⁻α¹α                    #  Decrement α
                          # Now the pointer is at the top left corner of the hexagon,
                          # from where the other smaller hexagons will soon be generated

Ho notato che non c'è "Ciao, mondo!" programma per Charcoal ancora. Dovresti aggiungerlo.
mbomb007,

@ mbomb007 Non sarebbe solo un duplicato della banale risposta "questa lingua stampa il suo file sorgente se non contiene comandi"?
Neil,

Ho salvato alcuni byte quando mi sono reso conto che ×_X²ιè lo stesso di ×__βe alcuni altri byte convertendo il tuo in a , il che evita anche di dover memorizzare il numero di input. Provalo online! .
Neil,

@Neil Grazie, è abbastanza bello :)
Kritixi Lithos,

5

Haskell , 230 217 207 byte

MODIFICARE:

  • -13 byte: @xnor ha visto che il mio #potrebbe essere giusto max.
  • -10 byte: E anche quello zipWithe ppotrebbe essere unito in un ?operatore, e che avrei (in qualche modo!) Reimplementato replicate.

mprende un Integere restituisce un String.

m n=unlines.foldr1 o$((2^n)&).(2^)<$>[0..n]
l&t|a<-c[l,2*t]" _",b<-[c[l-i,1,2*t+2*i-2,1,l-i]" / \\ "|i<-[1..t]]=a:b++r(r<$>o[a]b)
c=(concat.).z replicate
o=max?' '?""
f?e=z f.(++repeat e)
r=reverse
z=zipWith

Provalo online!

Come funziona

  • mè la funzione principale. Usa &per generare gli esagoni con un'imbottitura adeguata, quindi li piega insieme o.
  • l&tgenera un piccolo esagono di lunghezza laterale t, imbottito all'interno di una grande lunghezza laterale l, come un elenco di Stringlinee.
    • a è la linea superiore dell'esagono, con i trattini bassi.
    • bè un elenco delle altre linee nella metà superiore dell'esagono. Le linee di bsono centrate nell'imbottitura, che è rettangolare; questo consente al passaggio successivo di funzionare.
    • La metà inferiore dell'esagono viene asovrapposta sopra bcon o, quindi invertita (sia nell'ordine delle linee sia all'interno di ciascuna linea).
  • caccetta due argomenti, un elenco di lunghezze e una stringa e genera una stringa che contiene tante copie di ciascun carattere dell'originale della lunghezza corrispondente, ad es c[1,3,2]"abc" == "abbbcc". Viene utilizzato &per generare le linee.
  • o accetta due argomenti che rappresentano le immagini come elenchi di linee e sovrappone il primo, più piccolo sopra il secondo.
    • Viene utilizzato sia per combinare esagoni che per aggiungere il fondo a ciascun esagono.
    • Funziona essenzialmente usando ?due volte per riempire la prima immagine con infiniti spazi sia verso il basso che verso destra, quindi comprimendo i caratteri corrispondenti con max, che seleziona il carattere non spaziale se ce n'è uno.
  • (f?e)l mriempie un elenco laggiungendo infinitamente molti elementi "e", quindi comprime l'elenco risultante e l'elenco mcon la ffunzione.

1
Bella soluzione! Penso che (#)possa essere max.
xnor

1
Lo zippare può essere combinato con pa salvare byte: o=max?' '?"";f?e=z f.(++repeat e). Potrebbe essere più breve senza punti.
xnor

2
(\n->(<$[1..n]))lo è replicate.
xnor

@xnor replicate? Questo è solo imbarazzante. Sono troppo abituato <$[1..n]o [1..n]>>quasi sempre vincente. Tuttavia, non vedo come accorciare ?ulteriormente. Ho già provato a rendere pinutile e ++si trova nel posto sbagliato, facendo esplodere le cose flip.
Ørjan Johansen

3

JavaScript (ES6), 258 byte

f=(n,s=` `.repeat(1<<n),p=(n?f(n-1):`


`).replace(/(.*)\n/g,s+`$1 `+s)+s,t=`_`.repeat(2<<n))=>(s+t+s+`
`+s.replace(/ /g,"$'/$'$'  $`$`$`$`\\$'\n")).replace(/ /g,(c,i)=>p[i+(1<<n>>1)])+s.replace(/ /g,"$`\\$`$`  $'$'$'$'/$`\n").replace(/ +\/( *)\n$/,t+`/$1
`)
<input type=number min=0 oninput=o.textContent=f(+this.value)><pre id=o>

Spiegazione: Per gli esagoni dopo il primo, l'esagono precedente viene prima generato e riempito su ciascun lato (ciò dipende dal fatto che l'output è un rettangolo). (Per la prima intestazione, viene creata un'imbottitura fittizia.) I lati superiore e superiore dell'esagono vengono generati e tutti gli spazi si fondono con l'esagono precedente. (Ci sono alcuni trucchi per allineare gli esagoni; questo sarebbe più facile se fossero consentiti margini extra.) I lati inferiori dell'esagono vengono generati in modo analogo ai lati superiori e il fondo dell'esagono viene quindi riempito. Bisogna fare attenzione a restituire un output rettangolare, inclusa una nuova riga finale, affinché la ricorsione funzioni.


Quindi, stai dimostrando che questa, la Teflon e la Deep Dish Pizza, sono tutte costruzioni molto simili? È abbastanza pulito.
AdmBorkBork,

1
@AdmBorkBork Ho alcune altre risposte che lo fanno; quelle diagonali /sono popolari nell'arte ASCII e il replacemetodo è un modo relativamente economico per generarle in JavaScript.
Neil,

1<<n>>1: Bella simmetria ;-)
Luca

@Luke Potrei cambiare la variabile in, diciamo, vma purtroppo 1non è simmetrica in nessuno dei miei soliti caratteri.
Neil,

2

PHP, 337 byte

0 indicizzazione

$h=array_fill(0,1+2*$v=2**($c=$argn),str_pad("",4*$v));for(;1+$c;$c--)for($i=0;$i<$e=2**$c*2+1;$i++){$z=$e-$i<2;$y=$i&&$i<$e/2;$x=$i>=$e/2&$i<$e-1;$h[$i]=substr_replace($h[$i],$s=str_pad(!$y?$z|$x?"\\":"":"/",$e-1+$z-$y+$y*$i*2-$x+$x*2*($e-$i),$z|!$i?"_":" ").(!$y?$z|$x?"/":"":"\\"),$v-$z-$y*$i-$x*($e-$i),strlen($s));}echo join("\n",$h);

Provalo online!

allargato

$h=array_fill(0,1+2*$v=2**($c=$argn),str_pad("",4*$v)); # fill array with maximal width
for(;1+$c;$c--)  # greatest hexagon to lowest
for($i=0;$i<$e=2**$c*2+1;$i++){ # loop through the rows
    $z=$e-$i<2;$y=$i&&$i<$e/2;$x=$i>=$e/2&$i<$e-1; # booleans last first ad second half
    $h[$i]=substr_replace($h[$i], # replace substring
    $s=str_pad(
        $z?"\\":($y?"/":($x?"\\":"")),
        $e-1+$z-$y+$y*$i*2-$x+$x*2*($e-$i),
        $z|!$i?"_":" "
        ).(!$z?!$y?$x?"/":"":"\\":"/"), # with string for smaller hexagon
    $v-$z-$y*$i-$x*($e-$i), # at offset
    strlen($s));
}
echo join("\n",$h); # Output
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.