Esto fue inmensamente divertido. Gracias por publicar este desafío.
Divulgación completa: el idioma (Hexagony) no existía en el momento en que se publicó este desafío. Sin embargo, no lo inventé, y el lenguaje no fue diseñado para este desafío (o cualquier otro desafío específico).
){_2"_{\"{{""}"{'2//_.\><*\"\/_><[\]/3\'\_;|#__/(\2\'3_'}(#:|{$#{>_\//(#={/;01*&"\\_|[##={|}$_#></)]$_##|){*_.>.(/?#//~-="{}<_"=#/\}.>"%<.{#{x\"<#_/=&{./1#_#>__<_'\/"#|@_|/{=/'|\"".{/>}]#]>(_<\'{\&#|>=&{{(\=/\{*'"]<$_
Presentado hexagonalmente:
) { _ 2 " _ { \ "
{ { " " } " { ' 2 /
/ _ . \ > < * \ " \ /
_ > < [ \ ] / 3 \ ' \ _
; | # _ _ / ( \ 2 \ ' 3 _
' } ( # : | { $ # { > _ \ /
/ ( # = { / ; 0 1 * & " \ \ _
| [ # # = { | } $ _ # > < / ) ]
$ _ # # | ) { * _ . > . ( / ? # /
/ ~ - = " { } < _ " = # / \ } .
> " % < . { # { x \ " < # _ /
= & { . / 1 # _ # > _ _ < _
' \ / " # | @ _ | / { = /
' | \ " " . { / > } ] #
] > ( _ < \ ' { \ & #
| > = & { { ( \ = /
\ { * ' " ] < $ _
El programa en realidad no usa las #
instrucciones, así que usé ese carácter para mostrar qué celdas están realmente sin usar.
¿Cómo funciona este programa? Eso depende. ¿Quieres la versión corta o la larga?
Explicación breve
Para ilustrar lo que quiero decir con "línea" y "segmento" en la siguiente explicación, considere esta disección del resultado previsto:
segments →
│ │ │ │ │ │x lines
─┼───┼─┼─────────┼─┼───┼─ ↓
│ │ │ │ │xxx│
─┼───┼─┼─────────┼─┼───┘
│ │ │ │x│
─┼───┼─┼─────────┼─┘
│ │ │xxxxxxxxx│
─┼───┼─┼─────────┘
│ │x│
─┼───┼─┘
│xxx│
─┼───┘
x│
Con eso explicado, el programa corresponde al siguiente pseudocódigo:
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
Larga explicación
Consulte este diagrama de ruta de código codificado por color.
La ejecución comienza en la esquina superior izquierda. La secuencia de instrucciones ){2'"''3''"2}?)
se ejecuta (más algunas cancelaciones redundantes, como "{
etc.) siguiendo una ruta bastante complicada. Comenzamos con el puntero de instrucción # 0, resaltado en carmesí. A mitad de camino, cambiamos al # 1, comenzando en la esquina superior derecha y pintados en verde bosque. Cuando IP # 2 comienza en azul aciano (centro derecha), el diseño de la memoria es el siguiente:
A lo largo de todo el programa, los bordes etiquetados como 2a y 2b siempre tendrán el valor 2
(los usamos para calcular 2ⁿ⁺¹ y para dividir entre 2, respectivamente) y el borde etiquetado como 3 siempre será 3
(lo usamos para calcular 3ⁱ).
Llegamos a los negocios cuando entramos en nuestro primer bucle, resaltado en azul aciano. Este bucle ejecuta las instrucciones (}*{=&}{=
para calcular el valor 2ⁿ⁺¹. Cuando sale el bucle, se toma el camino marrón de la silla de montar, que nos lleva al Puntero de instrucción n. ° 3. Esta IP simplemente se mueve a lo largo del borde inferior hacia el oeste en amarillo dorado y pronto pasa el control a la IP # 4.
La ruta fucsia indica cómo IP # 4, comenzando en la parte inferior izquierda, avanza rápidamente a la línea de disminución , establece ch en 32
(el carácter de espacio) y seg en (el nuevo valor de) la línea . Es debido al decremento temprano que en realidad comenzamos con 2ⁿ⁺¹ − 1 y eventualmente experimentamos una última iteración con el valor 0. Luego ingresamos al primer bucle anidado .
Dirigimos nuestra atención al índigo ramificado, donde, después de una breve disminución de seg , vemos que ch se actualiza a x
solo si seg ahora es cero. Luego, n se establece en línea - seg para determinar el número real del segmento en el que estamos. Inmediatamente entramos en otro bucle, esta vez en el color justo del tomate.
Aquí, calculamos cuántas veces se puede dividir n (el número de segmento actual) por 2. Mientras el módulo nos dé cero, incrementaremos i y dividiremos n por 2. Cuando estemos satisfechos, n ya no es divisible. , nos ramificamos en el gris pizarra, que contiene dos bucles: primero eleva 3 a la potencia del i que calculamos, y luego genera ch muchas veces. Observe que el primero de estos bucles contiene un[
instrucción, que cambia el control a IP # 3, el que solo estaba dando pequeños pasos a lo largo del borde inferior anteriormente. El cuerpo del bucle (multiplicando por 3 y decrementando) es ejecutado por un solitario IP # 3, encarcelado en un ciclo interminable de color verde oliva oscuro a lo largo del borde inferior del código. Del mismo modo, el segundo de estos bucles de color gris pizarra contiene una ]
instrucción que activa IP # 5 para generar ch y decrementar, que se muestra aquí en rojo indio oscuro. En ambos casos, los punteros de instrucción atrapados en la servidumbre ejecutan obedientemente una iteración a la vez y ceden el control de nuevo a IP # 4, solo para esperar el momento en que se solicite su servicio una vez más. El gris pizarra, mientras tanto, se une a sus hermanos fucsia e índigo.
Como seg inevitablemente llega a cero, el bucle índigo sale al camino verde del césped, que simplemente genera el carácter de nueva línea y se fusiona rápidamente con el fucsia para continuar el bucle de línea . Más allá de la iteración final del bucle de línea, se encuentra el corto camino sabon ebon de la finalización final del programa.
(,],~3^#@~.)@]
lugar de(1,[:,1,"0~3*])
guardar 1 byte. Y si está bien con!
como salida char enu:32+
lugar de' #'{~
guardar otro.