Hexágonos incrustados!

18

Su tarea: dado un número entero n, generar un patrón de hexágono incrustado siguiendo las reglas a continuación, hasta la enésima profundidad.

Un hexágono incrustado tiene la forma básica de esto: ( n=0)

 __      
/  \
\__/

Hexágonos integrados n=1y n=2:

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

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

La longitud de cada lado es 2 veces la longitud del mismo lado en la profundidad anterior multiplicada por dos. Los lados superior e inferior tienen 2 caracteres de longitud n=0y el resto comienza con 1 carácter. Las longitudes de los lados que no son de arriba a abajo deben ser 2^nlargas ( OEIS: A000079 ) y los lados superior e inferior deben seguir la regla 2^(n+1)(el mismo OEIS).

Los hexágonos actuales están indexados en 0, puede optar por usar 1 indexado si lo desea.

Este es el , por lo que gana la respuesta más corta.

Camarada SparklePony
fuente
@LuisMendo Bien, cambiaré el nombre.
Camarada SparklePony
Puede ser difícil manejar una gran entrada (ej. 64). ¿Hay un límite para n?
Matthew Roh
@SIGSEGV No hay límite para n.
Camarada SparklePony
1
Sería divertido ver una respuesta en Hexagony :))
Sr. Xcoder
1
Je, los gráficos de tortuga de mi presentación de curva de Koch también pueden hacer esto (solo se modificó la primera función). Definitivamente demasiado tiempo para esto, sin embargo :)
Ørjan Johansen

Respuestas:

10

Carbón , 40 29 bytes

11 bytes guardados gracias a @Neil cambiando el ciclo while a un ciclo for entre otros trucos

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

Pruébalo en línea!

Explicación (obsoleta)

Este programa comienza generando el hexágono más grande, y luego hace los más pequeños uno por uno en un ciclo while (1 indexado). Como referencia, αes el número de entrada, βes la variable que contiene 2^(α-1)y ιes la variable iterativa en el bucle.

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
Kritixi Lithos
fuente
Me di cuenta de que no hay "¡Hola, mundo!" programa para carbón todavía. Deberías agregarlo.
mbomb007
@ mbomb007 ¿No sería eso simplemente un duplicado de la trivial respuesta de "este idioma imprime su archivo fuente si no contiene comandos"?
Neil
Ahorré algunos bytes cuando me di cuenta de que ×_X²ιes lo mismo ×__β, y algunos bytes más al convertirlos en a , lo que también evita tener que almacenar el número de entrada. Pruébalo en línea! .
Neil
@Neil Gracias, eso es bastante bueno :)
Kritixi Lithos
5

Haskell , 230 217 207 bytes

EDITAR:

  • -13 bytes: @xnor vio que mi #podría ser solomax .
  • -10 bytes: Y también eso zipWithy ppodría fusionarse en un ?operador, y eso (¡de alguna manera!) Se volvería a implementar replicate.

mtoma un Integery devuelve 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

Pruébalo en línea!

Cómo funciona

  • mEs la función principal. Se utiliza &para generar los hexágonos con el relleno adecuado, luego los dobla junto con o.
  • l&tgenera un pequeño hexágono de longitud lateral t, acolchado dentro de uno grande de longitud lateral l, como una lista de Stringlíneas.
    • a es la línea superior del hexágono, con los guiones bajos.
    • bes una lista de las otras líneas en la mitad superior del hexágono. Las líneas de bse centran en el relleno, que es rectangular; Esto permite que el siguiente paso funcione.
    • La mitad inferior del hexágono es asuperpuesto en la parte superior de bcon o, entonces invertido (tanto orden de las líneas y dentro de cada línea).
  • ctoma dos argumentos, una lista de longitudes y una cadena, y genera una cadena que tiene tantas copias de cada carácter en el original como la longitud correspondiente, por ejemplo c[1,3,2]"abc" == "abbbcc". Se utiliza &para generar las líneas.
  • o toma dos argumentos que representan imágenes como listas de líneas y superpone el primero, más pequeño, encima del segundo.
    • Se usa tanto para combinar hexágonos como para agregar el fondo a cada hexágono.
    • Básicamente funciona al usar ?dos veces para rellenar la primera imagen con infinitos espacios, tanto hacia abajo como hacia la derecha, y luego comprimir los caracteres correspondientes con max, que selecciona el carácter que no es espacio si hay uno.
  • (f?e)l mrellena una lista lagregando infinitos elementos 'e', ​​luego comprime la lista resultante y la lista mcon la ffunción.
Ørjan Johansen
fuente
1
Buena solución! Creo que (#)puede ser max.
xnor
1
El pasar con velocidad se puede combinar con pal ahorro bytes: o=max?' '?"";f?e=z f.(++repeat e). Podría ser más corto sin punto.
xnor
2
(\n->(<$[1..n]))es replicate.
xnor
@xnor replicate? Eso sí que es vergonzoso. Estoy demasiado acostumbrado <$[1..n]o [1..n]>>casi siempre estoy ganando. Sin embargo, no veo cómo acortar ?más. Ya intenté hacer un punto plibre y ++simplemente está en el lugar equivocado, explotando las cosas flip.
Ørjan Johansen
3

JavaScript (ES6), 258 bytes

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>

Explicación: Para los hexágonos después del primero, el hexágono anterior se genera primero y se rellena en cada lado (esto se basa en que la salida es un rectángulo). (Para el primer encabezado, se crea un relleno ficticio). Se generan los lados superior y superior del hexágono, y todos los espacios se fusionan con el hexágono anterior. (Hay algunos trucos para que los hexágonos se alineen; esto sería más fácil si se permitieran márgenes adicionales). Los lados inferiores del hexágono se generan de forma análoga a los lados superiores, y luego se rellena la parte inferior del hexágono. Se debe tener cuidado para devolver la salida rectangular, incluida una nueva línea final, para que la recursión funcione.

Neil
fuente
Entonces, ¿estás demostrando que esta, la de teflón y la de Deep Dish Pizza, son construcciones realmente similares? Eso es un poco ordenado.
AdmBorkBork
1
@AdmBorkBork Tengo algunas otras respuestas que hacen eso; esas diagonales /son populares en el arte ASCII y el replacemétodo es una forma relativamente barata de generarlas en JavaScript.
Neil
1<<n>>1: Buena simetría ;-)
Lucas
@Luke, podría cambiar la variable a, por ejemplo, vpero lamentablemente 1no es simétrica en ninguna de mis fuentes habituales.
Neil
2

PHP, 337 bytes

0 indexación

$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);

Pruébalo en línea!

Expandido

$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
Jörg Hülsermann
fuente