C'était extrêmement amusant. Merci d'avoir posté ce défi.
Divulgation complète: la langue (Hexagony) n'existait pas au moment où ce défi a été publié. Cependant, je ne l'ai pas inventé, et le langage n'a pas été conçu pour ce défi (ou tout autre défi spécifique).
){_2"_{\"{{""}"{'2//_.\><*\"\/_><[\]/3\'\_;|#__/(\2\'3_'}(#:|{$#{>_\//(#={/;01*&"\\_|[##={|}$_#></)]$_##|){*_.>.(/?#//~-="{}<_"=#/\}.>"%<.{#{x\"<#_/=&{./1#_#>__<_'\/"#|@_|/{=/'|\"".{/>}]#]>(_<\'{\&#|>=&{{(\=/\{*'"]<$_
Disposé en hexagone:
) { _ 2 " _ { \ "
{ { " " } " { ' 2 /
/ _ . \ > < * \ " \ /
_ > < [ \ ] / 3 \ ' \ _
; | # _ _ / ( \ 2 \ ' 3 _
' } ( # : | { $ # { > _ \ /
/ ( # = { / ; 0 1 * & " \ \ _
| [ # # = { | } $ _ # > < / ) ]
$ _ # # | ) { * _ . > . ( / ? # /
/ ~ - = " { } < _ " = # / \ } .
> " % < . { # { x \ " < # _ /
= & { . / 1 # _ # > _ _ < _
' \ / " # | @ _ | / { = /
' | \ " " . { / > } ] #
] > ( _ < \ ' { \ & #
| > = & { { ( \ = /
\ { * ' " ] < $ _
Le programme n'utilise pas réellement l' #
instruction. J'ai donc utilisé ce caractère pour indiquer quelles cellules sont réellement inutilisées.
Comment fonctionne ce programme? Ça dépend. Voulez-vous la version courte ou la version longue?
Courte explication
Pour illustrer ce que j'entends par «ligne» et «segment» dans l'explication suivante, considérons cette dissection de la sortie souhaitée:
segments →
│ │ │ │ │ │x lines
─┼───┼─┼─────────┼─┼───┼─ ↓
│ │ │ │ │xxx│
─┼───┼─┼─────────┼─┼───┘
│ │ │ │x│
─┼───┼─┼─────────┼─┘
│ │ │xxxxxxxxx│
─┼───┼─┼─────────┘
│ │x│
─┼───┼─┘
│xxx│
─┼───┘
x│
Avec cela expliqué, le programme correspond au pseudocode suivant:
n = get integer from stdin
# Calculate the number of lines we need to output.
line = pow(2, n+1)
while line > 0:
line = line - 1
# For all segments except the last, the character to use is spaces.
ch = ' ' (space, ASCII 32)
# The number of segments in each line is
# equal to the line number, counting down.
seg = line
while seg > 0:
seg = seg - 1
# For the last segment, use x’s.
if seg = 0:
ch = 'x' (ASCII 120)
# Calculate the actual segment number, where the leftmost is 1
n = line - seg
# Output the segment
i = pow(3, number of times n can be divided by 2)
i times: output ch
output '\n' (newline, ASCII 10)
end program
Longue explication
Veuillez vous référer à ce diagramme de chemin de code codé par couleur.
L'exécution commence dans le coin supérieur gauche. La séquence d'instructions ){2'"''3''"2}?)
est exécutée (plus quelques annulations redondantes, comme, "{
etc.) en suivant un chemin relativement compliqué. Nous commençons avec le pointeur d’instruction n ° 0, surligné en rouge. À mi-parcours, nous passons au n ° 1, en partant du coin supérieur droit et peints en vert forêt. Quand IP # 2 commence en bleu bleuet (au centre à droite), la disposition de la mémoire est la suivante:
Tout au long du programme, les arêtes étiquetées 2a et 2b auront toujours la valeur 2
(nous les utilisons pour calculer 2ⁿ⁺¹ et pour diviser par 2, respectivement) et l'arête étiquetée 3 sera toujours 3
(nous l'utilisons pour calculer 3).
Nous entrons dans les affaires en entrant dans notre première boucle, surlignée en bleu bleuet. Cette boucle exécute les instructions (}*{=&}{=
pour calculer la valeur 2ⁿ⁺¹. Lorsque la boucle se termine, le chemin brun de selle est emprunté, ce qui nous conduit au pointeur d’instruction n ° 3. Cette IP ne fait que barboter le long du bord inférieur à l’ouest en verge d’or jaune et passe rapidement sous le contrôle de l’IP # 4.
Le chemin fuchsia indique comment l’IP n ° 4, en commençant par le coin inférieur gauche, procède rapidement pour décrémenter la ligne , régler ch sur 32
(le caractère espace) et seg sur la (nouvelle valeur de) ligne . C’est en raison de la décrémentation précoce que nous commençons réellement par 2ⁿ⁺¹ − 1 et finissons par subir une dernière itération avec la valeur 0. Nous entrons ensuite dans la première boucle imbriquée .
Nous tournons notre attention vers l'indigo ramifié, où, après un bref décrément de seg , nous voyons que chx
n'est mis à jour que si seg est maintenant à zéro. Ensuite, n est réglé sur line-seg pour déterminer le numéro réel du segment dans lequel nous sommes. Immédiatement, nous entrons dans une autre boucle, cette fois dans la couleur claire de la tomate.
Ici, nous calculons combien de fois n (le numéro de segment actuel) peut être divisé par 2. Tant que le modulo nous donne zéro, nous incrémentons i et divisons n par 2. Lorsque nous sommes satisfaits, n n'est plus divisible de la sorte , nous passons au gris ardoise, qui contient deux boucles: premièrement, il élève 3 à la puissance du i calculé, puis il émet ch le nombre de fois. Notez que la première de ces boucles contient un[
instruction, qui bascule le contrôle sur IP # 3 - celui qui ne prenait que des pas le long du bord inférieur plus tôt. Le corps de la boucle (multipliant par 3 et décrémentant) est exécuté par un IP solitaire n ° 3, emprisonné dans un cercle vert olive sans fin le long du bord inférieur du code. De même, la seconde de ces boucles gris ardoise contient une ]
instruction qui active l’IP n ° 5 pour la sortie des canaux et des décrémentations, représentée ici en rouge indien foncé. Dans les deux cas, les pointeurs d’instruction pris au piège de la servitude exécutent docilement une itération à la fois et cèdent le contrôle à l’IP 4, pour attendre que leur service soit de nouveau appelé. Le gris ardoise, quant à lui, rejoint ses frères fuchsia et indigo.
Lorsque seg atteint inévitablement zéro, la boucle indigo se termine dans le chemin vert de la pelouse, qui ne fait que sortir le caractère de nouvelle ligne et se fond rapidement dans le fuchsia pour continuer la boucle de ligne . Au-delà de l'itération finale de la boucle de ligne , se trouve le court chemin ebon de la fin du programme.
(,],~3^#@~.)@]
au lieu d'(1,[:,1,"0~3*])
enregistrer 1 octet. Et si vous êtes d'accord avec!
comme caractère de sortieu:32+
au lieu d'en' #'{~
sauvegarder un autre.