Antecedentes
Fractran es un lenguaje de programación esotérico completo de Turing inventado por John Conway. Un programa Fractran consiste en una lista ordenada de fracciones. El programa comienza tomando un solo entero como entrada. Cada iteración del programa, busca en la lista la primera fracción de tal manera que multiplicar el número por esa fracción produce otro número entero. Luego repite este proceso con el nuevo número, comenzando de nuevo al comienzo de la lista. Cuando no hay una fracción en la lista que pueda multiplicarse con el número, el programa termina y da el número como salida.
La razón por la que Fractran es Turing completo es porque simula una máquina de registro. La factorización prima del número almacena el contenido de los registros, mientras que la división y multiplicación es una forma de sumar y restar condicionalmente de los registros. Recomendaría leer el artículo de Wikipedia (vinculado a arriba).
El reto
Su tarea es escribir el programa más corto posible que pueda tomar un programa Fractran válido de STDIN como su única entrada y genere un programa BF válido a STDOUT que simule el programa Fractran. Hay dos formas de simular un programa Fractran con BF.
NOTA: Su respuesta no es un programa BF. Su respuesta es el código que genera el programa BF de cualquier programa de Fractran. El objetivo es lograr que el programa BF sea el equivalente del programa Fractran. (técnicamente podrías hacer la competencia en BF, pero sería difícil)
Opción 1
Su programa debería generar un programa BF que haga lo siguiente:
- Toma exactamente 1 número de STDIN en la forma del carácter ASCII correspondiente (debido a la forma en que funciona la entrada BF), que es la entrada al programa Fractran.
- Imprime exactamente 1 número en STDOUT en la forma del carácter ASCII correspondiente, que es la salida del programa Fractran.
Esta opción está destinada a representar la entrada y salida exactas de una máquina virtual Fractran.
opcion 2
El código BF que produce su programa debe hacer lo siguiente:
- Tome la entrada teniendo la factorización prima del número ya codificado en la memoria (antes de ejecutar el programa). Si la entrada es 28 (2 * 2 * 7), habrá un valor de 2 en la segunda celda y un valor de 1 en la séptima celda (el puntero comienza en la celda 0). Todas las demás celdas serán cero.
- Proporcione salida al tener la factorización prima de la salida codificada en la memoria cuando finalice el programa. Si la salida es 10, entonces debe haber un valor de 1 en cada una de las celdas 2 y 5. Todas las demás celdas con números primos deben tener un valor de cero. El contenido de otras células no importa.
Esta opción representa el modelo informático detrás del lenguaje Fractran.
Reglas y requisitos
- La entrada (encabeza tu programa) será una lista de fracciones en STDIN. Habrá una fracción por línea con una coma entre el numerador y el denominador. Una línea vacía representa el final de la entrada. Las fracciones siempre se reducirán a los términos más bajos.
- La salida de su programa debe ser un programa BF válido de una sola línea para STDOUT. Este programa debería poder simular ese programa Fractran en particular de acuerdo con una de las dos opciones. Para cualquier entrada, el programa BF generado debería poder producir la misma salida que el programa Fractran.
- Debe indicar qué opción eligió.
- Puede elegir los límites en la memoria BF y la cinta, y si están envolviendo
- CÓDIGO GOLF. Además, el tamaño de los programas BF emitidos no importa, solo el tamaño del programa que realiza la conversión.
- Los programas solo deben consistir en ASCII imprimible
Si soy ambiguo en alguna parte, no dudes en preguntar. Este es un desafío muy complicado de describir.
Además, publique el código BF generado de su programa para la siguiente entrada, a fin de proporcionar una manera fácil de verificar si su programa está funcionando:
33,20
5,11
13,10
1,5
2,3
10,7
7,2
Este programa calcula el número de 1s en la expansión binaria de un número. Sin embargo, la entrada y la salida tienen un formato extraño (como con todos los programas de Fractran). La entrada tiene la forma 2 ^ A, mientras que la salida tiene la forma 13 ^ B.
fuente
Respuestas:
Python, 182 caracteres
Opción 1, celdas de bytes estándar. Solo hay 255 entradas posibles (0 como entrada realmente no tiene sentido), por lo que solo ejecuto un intérprete de Fractran 255 veces en Python y genero un programa Brainfuck de búsqueda de tabla simple que codifica los resultados.
Salida para la entrada de ejemplo (
___
= 246 condiciones anidadas más, no puedo pegar todo el resultado ya que es demasiado grande):fuente
Python, 420 caracteres
Esto utiliza una especie de combinación de opciones 1 y 2: se supone que brainfuck se implementa con grandes números enteros (uso una implementación de Sage). Entrada de un programa fractran, por ejemplo,
33/20,5/11,13/10,1/5,2/3,10/7,7/2
. Luego, precargue un número, por ejemplo2^5
, en el cursor. Luego, ejecute la salida de este script de Python. Espera 44 segundos. El resultado, se13^2
encuentra donde comenzó el cursor. No esperé la respuesta2^7
.Este es mi primer script de brainfuck. Ciertamente se puede jugar más, pero tengo otras cosas que hacer hasta más tarde esta noche.
editar: en lugar de jugar más al golf, estoy trabajando en una solución para la opción 2. Además, aquí está el resultado del programa solicitado:
fuente
2^7
con mi intérprete Brainfuck en menos de 5 segundos. Además, ¿no debería ser enraw_input()
lugar deraw_input
(o es una peculiaridad que no conozco)?raw_input()
es necesario. No estoy sorprendido de que los intérpretes competentes de brainfuck lo hagan mejor que mi implementación ingeniosa de Sage.Perl, 326 caracteres
Voy a responder mi propia pregunta con suerte para estimular más respuestas. Por supuesto, no soy elegible para ganar. Esta es la opción 2 con memoria y celdas ilimitadas, aunque funciona en celdas de ajuste. Cada fracción se convierte en un solo bloque de código. Las nuevas líneas son para facilitar la lectura.
Aquí está el resultado de ejemplo. Esto aprovecha el hecho de que otros personajes son ignorados como comentarios. Esto también parece ser una salida muy corta en comparación con las otras entradas, aunque el tamaño de salida técnicamente no importa.
fuente
Sabio, 431 caracteres
Esta es una solución completamente nueva. Descubrí algunas formas mejores de hacer las cosas en brainfuck, y esto implementa correctamente la Opción 2. Se agregaron nuevas líneas para mayor claridad. Esto probablemente se pueda jugar más, pero implica reescribir el BF para tener una profundidad de bucle más baja.
Salida de muestra:
Dada la entrada
33/20,5/11,13/10,1/5,2/3,10/7,7/2
fuente