Hexagones intégrés!

18

Votre tâche: étant donné un entier n, générez un motif hexagonal incorporé en suivant les règles ci-dessous, jusqu'à la nième profondeur.

Un hexagone intégré a la forme de base de ceci: ( n=0)

 __      
/  \
\__/

Hexagones intégrés n=1et n=2:

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

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

La longueur de chaque côté est 2 fois la longueur du même côté dans la profondeur précédente multipliée par deux. Les côtés supérieur et inférieur sont de 2 caractères lorsque n=0et le reste commence par 1 caractère. Les longueurs des côtés non supérieur-inférieur doivent être 2^nlongues ( OEIS: A000079 ) et les côtés supérieur et inférieur doivent suivre la règle 2^(n+1)(même OEIS).

Les hexagones actuels sont indexés 0, vous pouvez choisir d'utiliser un index 1 si vous le souhaitez.

Il s'agit de , donc la réponse la plus courte l'emporte!

Camarade SparklePony
la source
@LuisMendo D'accord, je vais changer le nom.
Camarade SparklePony le
Il peut être difficile de gérer de grandes entrées (ex. 64). Y a-t-il une limite à n?
Matthew Roh
@SIGSEGV Il n'y a pas de limite à n.
Camarade SparklePony
1
Serait amusé de voir une réponse dans Hexagony :))
M. Xcoder
1
Hé, les graphiques de tortue de ma soumission de courbe de Koch peuvent aussi le faire (seule la première fonction a changé). Certainement trop long pour cela, cependant :)
Ørjan Johansen

Réponses:

10

Fusain , 40 29 octets

11 octets économisés grâce à @Neil en changeant la boucle while en une boucle for parmi d'autres astuces

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

Essayez-le en ligne!

Explication (obsolète)

Ce programme commence par générer le plus grand hexagone, puis fait les plus petits un par un dans une boucle while (indexé 1). Pour référence,α est le numéro d'entrée, βest la variable qui contient 2^(α-1)et ιest la variable d'itération dans la boucle.

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
la source
J'ai remarqué qu'il n'y a pas de "Bonjour, monde!" programme pour le charbon de bois encore. Vous devez l'ajouter.
mbomb007
@ mbomb007 Ne serait-ce pas simplement un doublon de la réponse triviale "ce langage imprime son fichier source s'il ne contient aucune commande"?
Neil
J'ai enregistré quelques octets lorsque j'ai réalisé que ×_X²ιc'était la même chose que ×__β, et quelques octets supplémentaires en convertissant votre en un , ce qui évite également d'avoir à stocker le numéro d'entrée. Essayez-le en ligne! .
Neil
@Neil Merci, c'est plutôt bien :)
Kritixi Lithos
5

Haskell , 230 217 207 octets

ÉDITER:

  • -13 octets: @xnor a vu que mon #pouvait être juste max.
  • -10 octets: Et aussi cela zipWithet ppourrait être fusionné en un ?opérateur, et que j'avais (en quelque sorte!) Réimplémenté replicate.

mprend un Integeret retourne 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

Essayez-le en ligne!

Comment ça fonctionne

  • mest la fonction principale. Il utilise &pour générer les hexagones avec un rembourrage approprié, puis les plie avec o.
  • l&tgénère un petit hexagone de longueur latérale t, rembourré à l'intérieur d'un grand de longueur latérale l, sous forme de liste de Stringlignes.
    • a est la ligne supérieure de l'hexagone, avec les traits de soulignement.
    • best une liste des autres lignes dans la moitié supérieure de l'hexagone. Les lignes de bsont centrées dans le rembourrage, qui est rectangulaire; cela permet à la prochaine étape de fonctionner.
    • La moitié inférieure de l'hexagone est asuperposé au - dessus de bà o, alors inversée ( à la fois l' ordre de lignes et dans chaque ligne).
  • cprend deux arguments, une liste de longueurs et une chaîne, et génère une chaîne qui a autant de copies de chaque caractère dans l'original que la longueur correspondante, par exemple c[1,3,2]"abc" == "abbbcc". Il est utilisé &pour générer les lignes.
  • o prend deux arguments représentant des images sous forme de listes de lignes et superpose le premier, le plus petit au-dessus du second.
    • Il est utilisé à la fois pour combiner des hexagones et pour ajouter le fond à chaque hexagone.
    • Il fonctionne essentiellement en utilisant ?deux fois pour remplir la première image avec une infinité d'espaces vers le bas et vers la droite, puis en zippant les caractères correspondants avec max, qui sélectionne le caractère non-espace s'il y en a un.
  • (f?e)l mremplit une liste len ajoutant une infinité d'éléments «e», puis zippe la liste résultante et la liste mavec la ffonction.
Ørjan Johansen
la source
1
Bonne solution! Je pense que c'est (#)possible max.
xnor
1
Le Zipping peut être combiné avec péconomiser des octets: o=max?' '?"";f?e=z f.(++repeat e). Pourrait être plus court sans point.
xnor
2
(\n->(<$[1..n]))est replicate.
xnor
@xnor replicate? Maintenant, c'est juste gênant. Je suis juste trop habitué <$[1..n]ou [1..n]>>presque toujours gagnant. Cependant, je ne vois pas comment raccourcir ?davantage. J'ai déjà essayé de faire sans ppoint et le ++est juste au mauvais endroit, faisant exploser les choses avec flip.
Ørjan Johansen
3

JavaScript (ES6), 258 octets

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>

Explication: Pour les hexagones après le premier, l'hexagone précédent est d'abord généré et complété de chaque côté (cela dépend de la sortie qui est un rectangle). (Pour le premier titre, un remplissage factice est créé.) Les côtés supérieur et supérieur de l'hexagone sont générés et tous les espaces fusionnés avec l'hexagone précédent. (Il y a une astuce pour aligner les hexagones; ce serait plus facile si des marges supplémentaires étaient autorisées.) Les côtés inférieurs de l'hexagone sont générés de manière analogue aux côtés supérieurs, et le bas de l'hexagone est ensuite rempli. Il faut prendre soin de renvoyer une sortie rectangulaire, y compris une nouvelle ligne de fin, pour que la récursivité fonctionne.

Neil
la source
Donc, vous démontrez que celle-ci, celle en téflon et celle en Deep Dish Pizza, sont toutes de construction vraiment similaire? C'est plutôt bien.
AdmBorkBork
1
@AdmBorkBork J'ai quelques autres réponses qui font ça; ces diagonales /sont populaires dans l'art ASCII et la replaceméthode est un moyen relativement bon marché de les générer en JavaScript.
Neil
1<<n>>1: Symétrie sympa ;-)
Luke
@Luke Je pourrais changer la variable en, disons, vmais malheureusement, ce 1n'est symétrique dans aucune de mes polices habituelles.
Neil
2

PHP, 337 octets

0 Indexation

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

Essayez-le en ligne!

Étendu

$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
la source