Hexágonos incorporados!

18

Sua tarefa: dado um número inteiro n, gere um padrão hexagonal incorporado seguindo as regras abaixo, até a enésima profundidade.

Um hexágono incorporado possui a forma básica disso: ( n=0)

 __      
/  \
\__/

Hexágonos incorporados n=1e n=2:

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

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

O comprimento de cada lado é 2 vezes o comprimento do mesmo lado na profundidade anterior duas vezes. Os lados superior e inferior têm 2 caracteres quando n=0e o restante começa com 1 caractere. Os comprimentos dos lados não superior e inferior devem ser 2^nlongos ( OEIS: A000079 ) e os lados superior e inferior devem seguir a regra 2^(n+1)(o mesmo OEIS).

Os hexágonos atuais são indexados em 0; você pode optar por usar o indexado em 1, se desejar.

Isso é , então a resposta mais curta vence!

Camarada SparklePony
fonte
@LuisMendo Ok, vou mudar o nome.
precisa saber é o seguinte
Pode ser difícil lidar com grandes entradas (ex. 64). Existe um limite para n?
Matthew Roh
@SIGSEGV Não há limite para n.
precisa saber é o seguinte
1
Seria divertido ver uma resposta em Hexagony :))
Mr. Xcoder
1
Heh, os gráficos das tartarugas da minha curva de Koch também podem fazer isso (apenas a primeira função foi alterada). Definitivamente muito tempo para isso, embora :)
Ørjan Johansen

Respostas:

10

Carvão , 40 29 bytes

11 bytes salvos graças ao @Neil, alterando o loop while para um loop for, entre outros truques

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

Experimente online!

Explicação (desatualizada)

Este programa começa com a geração do maior hexágono e, em seguida, executa os menores um a um em um loop while (indexado a 1). Para referência, αé o número de entrada, βé a variável que contém 2^(α-1)e ιé a variável de iteração no loop.

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
fonte
Notei que não há "Olá, mundo!" programa para carvão ainda. Você deve adicioná-lo.
mbomb007
@ mbomb007 Isso não seria apenas uma duplicata da resposta trivial "esta linguagem imprime seu arquivo de origem se não contiver comandos"?
Neil
Salvei alguns bytes quando percebi que ×_X²ιé o mesmo que ×__β, e mais alguns bytes convertendo seu em um , o que também evita a necessidade de armazenar o número de entrada. Experimente online! .
Neil
@Neil Graças, que é bastante puro :)
Kritixi Lithos
5

Haskell , 230 217 207 bytes

EDITAR:

  • -13 bytes: @xnor viu que meu #poderia ser justo max.
  • -10 bytes: e também isso zipWithe ppoderia ser mesclado em um ?operador e que eu (de alguma forma!) Reimplementado replicate.

mpega um Integere retorna um 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

Experimente online!

Como funciona

  • mé a função principal. Ele usa &para gerar os hexágonos com preenchimento adequado e depois os dobra o.
  • l&tgera um pequeno hexágono de comprimento lateral t, acolchoado dentro de um grande de comprimento lateral l, como uma lista de Stringlinhas.
    • a é a linha superior do hexágono, com sublinhados.
    • bé uma lista das outras linhas na metade superior do hexágono. As linhas de bsão centralizadas no preenchimento, que é retangular; isso permite que o próximo passo funcione.
    • A metade inferior do hexágono é asobreposto no topo dos bcom o, em seguida, invertida (tanto a ordem das linhas e, dentro de cada linha).
  • crecebe dois argumentos, uma lista de comprimentos e uma sequência, e gera uma sequência que possui tantas cópias de cada caractere no original quanto o comprimento correspondente, por exemplo c[1,3,2]"abc" == "abbbcc". É usado &para gerar as linhas.
  • o pega dois argumentos representando imagens como listas de linhas e sobrepõe o primeiro, menor, em cima do segundo.
    • É usado para combinar hexágonos e adicionar o fundo a cada hexágono.
    • Essencialmente, ele funciona usando ?duas vezes para preencher a primeira imagem com infinitos espaços, tanto para baixo quanto para a direita, e depois agrupando os caracteres correspondentes com max, que seleciona o caractere não espacial, se houver um.
  • (f?e)l mpreenche uma lista lanexando infinitamente muitos elementos 'e' e fecha a lista resultante e a lista mcom a ffunção
Ørjan Johansen
fonte
1
Ótima solução! Eu acho que (#)pode ser max.
Xnor
1
O fechando podem ser combinados com pa salvar bytes: o=max?' '?"";f?e=z f.(++repeat e). Pode ser mais curto sem ponto.
Xnor
2
(\n->(<$[1..n]))é replicate.
Xnor
@xnor replicate? Agora isso é apenas embaraçoso. Estou acostumado demais <$[1..n]ou [1..n]>>quase sempre ganhando. No entanto, não vejo como diminuir ?ainda mais. Eu já tentei fazer o ppointfree e ele ++está no lugar errado, explodindo as coisas 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>

Explicação: Para hexágonos após o primeiro, o hexágono anterior é primeiro gerado e preenchido em cada lado (isso depende da saída ser um retângulo). (Para o primeiro cabeçalho, é criado algum preenchimento fictício.) Os lados superior e superior do hexágono são gerados e todos os espaços são mesclados com o hexágono anterior. (Existem alguns truques para alinhar os hexágonos; isso seria mais fácil se margens extras fossem permitidas.) Os lados inferiores do hexágono são gerados analogamente aos lados superiores, e a parte inferior do hexágono é preenchida. É necessário tomar cuidado para retornar a saída retangular, incluindo uma nova linha à direita, para que a recursão funcione.

Neil
fonte
Então, você está demonstrando que esse, o Teflon e o Deep Dish Pizza, são todos de construção realmente semelhante? Isso é meio arrumado.
AdmBorkBork
1
@AdmBorkBork Tenho outras respostas que fazem isso; essas diagonais /são populares na arte ASCII e o replacemétodo é uma maneira relativamente barata de gerá-las em JavaScript.
711 Neil
1<<n>>1: Simetria agradável ;-)
Lucas
@ Lucas Eu poderia mudar a variável para, digamos, vmas infelizmente 1não é simétrica em nenhuma das minhas fontes usuais.
911 Neil
2

PHP, 337 bytes

0 Indexação

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

Experimente online!

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
fonte