Esto fue sorprendentemente complicado, y no estoy convencido de que sea óptimo ...
<.@!$?
Después de rellenar y desplegar el código, esto representa la siguiente cuadrícula hexadecimal:
Esto utiliza un flujo de control similar al de mi reciente programa de gato libre de errores , que se mueve a lo largo de antiagoniales. Para lograr eso, comenzamos desviando el puntero de instrucción (IP) hacia la izquierda, donde el camino púrpura se envuelve hacia la esquina inferior izquierda.
?
lee la entrada como un entero. !
lo imprime de nuevo. .
es solo un no-op. Ahora la esquina de la cuadrícula actúa como una rama:
Si la entrada fue 0
, la IP continuará a lo largo de la ruta roja, que simplemente termina el programa con @
.
Si la entrada fue 1
, la IP continuará en el camino verde. De nuevo, .
es solo un no-op, pero $
es el equivalente del trampolín de Befunge: omite la siguiente instrucción. Después del ajuste, la siguiente instrucción sería ?
, pero debido a la $
ejecución, en realidad continúa en la ruta azul, comenzando con la !
impresión de otra copia del archivo 1
. Este ciclo que solo contiene !..$
ahora se repite indefinidamente.
Un estudio del flujo de control en Hexagony ...
Creo que la solución anterior es óptima. He escrito un forzador bruto, que verifica todos los programas de Hexagonía de 6 bytes, que contienen al menos uno de cada uno ?!@
(que son necesarios; También he verificado :
y %
en lugar de @
terminar con un error de división por cero, pero eso tampoco ayudó). La verificación imprime todos los programas que a) producen una 0
entrada 0
y terminan yb) producen al menos dos 1
s (y nada más) y no terminan dentro de los primeros 60 ticks del programa (200 ticks para soluciones de 5 bytes) . Dudo que cualquier solución válida requiera más de 200 ticks para imprimir correctamente la primera 0
o la segunda 1
en una cuadrícula tan pequeña, así que no creo que me haya perdido ninguna solución potencial.
La búsqueda no arrojó ningún resultado para 5 bytes, pero 57 resultados para 6 bytes (usando @
; no hay necesidad de terminar con un error si podemos resolver esto limpiamente en la misma cantidad de bytes). De esos 57, solo 6 eran falsos positivos que en realidad imprimieron solo dos 1
sy luego entraron en un bucle infinito sin imprimir más. Una solución se enumeró dos veces porque contenía dos !
comandos. Eso deja exactamente 50 soluciones válidas.
Hay una cierta cantidad de degeneración entre las soluciones donde uno o dos caracteres no son sustanciales, por ejemplo, porque de todos modos son efectivamente no operativos. Las soluciones se pueden agrupar en 23 conjuntos de programas genuinamente distintos (en algunos casos, solo hay una única diferencia de caracteres entre dos conjuntos, pero cambia sustancialmente el flujo de control, por lo que los he contado por separado). Dos de los grupos incluso utilizan múltiples punteros de instrucción de una manera muy inesperada. Como nunca habría ideado la mayoría de estas formas de usar las ramas y los espejos, hacen un estudio muy interesante sobre qué tipos de flujo de control son posibles en Hexagony, y definitivamente he aprendido algunos trucos nuevos para futuros campos de golf.
El flujo de control general es casi siempre el mismo: lea un número, imprímalo. Si se trata de 0
encontrar una forma de hacerlo @
, si no, sigue recorriendo el !
tiempo mientras mantienes un valor de borde de 1
. Hay cuatro excepciones notables:
- Una solución (la que tiene dos
!
) imprime dos 1
s por iteración a través de la cuadrícula, por lo tanto, imprime aproximadamente el doble de rápido que la mayoría de los programas. He marcado este con x2
abajo.
- Algunas soluciones (las que contienen un
o
) reemplazan el 1
con a 111
(el código de carácter de o
), por lo que imprimen tres 1
s por iteración, lo que hace que impriman aproximadamente tres veces más rápido que la mayoría de los programas. Los he marcado con x3
abajo.
- Dos soluciones anexar una
1
con el valor de punta en cada iteración (por lo que 1
-> 11
-> 111
-> ...). Esos imprimen muy rápido, pero eventualmente se quedarán sin memoria. Los he marcado con OoM
abajo.
- Dos soluciones entran en un bucle muy cerrado que simplemente rebota hacia adelante y hacia atrás
!
, imprimiendo en cada tictac (en lugar de cada 5 o más o menos), lo que las hace un poco más rápidas (y más ordenadas). Los he marcado con ><
abajo.
Así que aquí está todo el zoológico:
#1 #5 #12 #19
?!/$.@ ?$!>$@ .?!/$@ |!|?$@ # ><
?!/$1@ # OoM ?$!|$@ =?!/$@
?!/$=@ #20
?!/$\@ #6 #13 $@.?<!
?!/$o@ # x3 ?/!<|@ .?/!$@ $@1?<! # OoM
?!/$!@ # x2 =?/!$@ $@=?<!
#7 $@o?<! # x3
#2 ?\!<|@ #14
?!>$)@ \!?__@ #21
?!>$1@ #8 _>_!?@
?!>$o@ # x3 ?<!>$@ # >< #15
?!|$)@ \_?!$@ #22
?!|$1@ #9 <!@.$?
?!|$o@ # x3 ?\$!@$ #16 <!@/$?
\_?!_@ <!@=$?
#3 #10 <$@!$?
?!|)$@ ?~#!@) #17 <.@!$?
?!|1$@ ?~#!@1 $$?\@! </@!$?
?!|o$@ # x3 <=@!$?
#11 #18
#4 ?$)\@! \$?\@! #23
?_!<@> ?$1\@! <<@]!?
?$o\@! # x3
El siguiente es un breve recorrido para un puñado de los grupos más representativos. Especialmente los grupos 10 y 23 valen la pena echarle un vistazo. Hay muchos otros caminos interesantes y a veces complicados en los otros grupos, pero creo que ya te aburrí lo suficiente al final de esto. Para cualquiera que realmente quiera aprender Hexagony, definitivamente vale la pena investigarlos, ya que exhiben aún más usos posibles de los espejos y $
.
Grupo 1
Esta no es mucho más elaborada que mi solución original, pero los caminos van en diferentes direcciones. También permite la mayor cantidad de variaciones en una sola celda, ya que el no-op más a la derecha se puede reemplazar con 5 comandos diferentes que aún lo hacen válido sin cambiar la estructura:
Grupo 2
Este es bastante interesante, porque solo se mueve horizontalmente. Después de ajustarse al >
, la IP se invierte inmediatamente, tomando la rama en la esquina. No es del todo visible el diagrama, pero en el caso de 1
que recorramos la primera fila de nuevo, pero esta vez hacia atrás. Esto también significa que nos encontramos ?
nuevamente, que ahora regresa 0
(EOF). Esto se arregla con )
(incremento) para seguir imprimiendo 1
s. Esto también tiene 5 variaciones, como )
también podría ser 1
o o
, y >
también podría ser |
:
Grupo 3
Este parece casi idéntico al anterior, pero es desordenado como el infierno. Hasta golpear |
y luego atravesar la fila inferior o superior es lo mismo. Pero en el caso de un bucle, el $
ahora salta el )
en el espejo. Entonces seguimos el camino turquesa hacia la derecha, ahora tocamos el incremento, saltamos el @
antes de pasar al de |
nuevo y luego volvemos al camino verde en la parte superior.
Grupo 4
Pensé que este era particularmente ingenioso:
El _
espejo en la esquina superior derecha es inicialmente no operativo, por lo que imprimimos con !
y presionamos el botón <
. El 0
camino ahora golpea el espejo horizontal y termina. Sin 1
embargo, el camino toma una trayectoria realmente interesante: se desvía hacia abajo, se envuelve !
hacia la horizontal, se redirige hacia la horizontal y luego se envuelve hacia atrás !
nuevamente . Luego sigue moviéndose en esta forma de rombo, imprimiendo dos veces por iteración (cada tercer tic).
Grupo 8
Esta es una de las dos soluciones con un ciclo de impresión realmente ajustado:
Los <
actos como la rama. Después de envolver dos veces, 0
golpes @
. 1
por otro lado, primero omite el ?
, luego lo >
envía al de $
nuevo, por lo que se omite el @
. Luego, la IP se envuelve en el camino turquesa, donde rebota hacia adelante y hacia atrás entre >
y <
(envolviendo el borde en el medio).
Grupo 10
Uno de los dos grupos que utilizan otros punteros de instrucción, y es absolutamente hermoso. Hexagony tiene 6: cada uno comienza desde una esquina diferente a lo largo del borde en el sentido de las agujas del reloj, pero solo uno de ellos está activo a la vez.
Como de costumbre, leemos con ?
. Ahora ~
es la negación unaria: convierte el 1
a -1
. A continuación, tocamos el #
. Esta es una forma de cambiar entre IP: toma el valor de borde actual módulo 6 y cambia a la IP correspondiente (las IP están numeradas 0
en el sentido de las agujas del reloj). Entonces, si la entrada fue 0
, entonces la IP simplemente sigue siendo la misma, y viaja aburridamente hacia adelante !@
. Pero si la entrada fue 1
, entonces el valor actual es -1
cuál es 5 (mod 6)
. Entonces cambiamos a la IP que comienza en la misma celda (la ruta verde). Ahora #
es un no-op y ?
establece el borde de la memoria en 0
. )
incrementos para !
imprimir a 1
. Ahora golpeamos ~
nuevamente para asegurarnos de que#
sigue siendo un no-op (en lugar de cambiarnos a IP 1 que terminaría el programa). Es sorprendente lo bien que todo encaja en este pequeño programa.
Grupo 22
Solo para tener en cuenta, este es el grupo en el que se encuentra mi solución original. También es el grupo más grande, porque el no-op puede estar en dos lugares diferentes, y hay varias opciones para el comando real (no-op efectivo).
Grupo 23
Este es el otro grupo que usa múltiples IP. De hecho, este utiliza 3 IP diferentes. La esquina superior derecha es un poco desordenada, pero intentaré guiarte a través de esto:
Entonces, el comienzo que has visto antes: <
desvía el noreste, ?
lee la entrada. Ahora ]
es otra forma de cambiar entre IP: le da el control a la siguiente IP en el sentido de las agujas del reloj. Así que cambiamos el control al camino turquesa que (sé que es difícil de ver) comienza en la esquina noreste que va hacia el sureste. Se refleja de inmediato en el <
modo que se envuelve en la esquina sureste, en dirección noroeste. Es también golpea el ]
por lo que cambiar a la siguiente IP. Este es el camino gris que comienza en la esquina este, hacia el suroeste. Imprime la entrada, luego se envuelve a la esquina noreste. <
desvía el camino hacia la horizontal, donde es reflejado por el otro <
. Ahora la mano derecha<
actúa como una rama: si la entrada fue 0
, la IP se mueve hacia el noreste y se ajusta al @
. Si la entrada fue 1
, la IP se mueve hacia el !
, se envuelve hacia la izquierda y <
donde se refleja ... ahora en la esquina, se devuelve al !
, se desvía por la derecha <
, se refleja por la izquierda <
y comienza el camino terminado...
Todo un desastre, pero un desastre hermoso. :)
Diagramas generados con el sorprendente HexagonyColorer de Timwi .