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 Win a F, 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.