fundo
Fractran é uma linguagem de programação esotérica completa de Turing inventada por John Conway. Um programa Fractran consiste em uma lista ordenada de frações. O programa começa com um único número inteiro como entrada. A cada iteração do programa, ele pesquisa na lista a primeira fração, de modo que multiplicar o número por essa fração produz outro número inteiro. Em seguida, repete esse processo com o novo número, começando no início da lista. Quando não há fração na lista que possa ser multiplicada pelo número, o programa termina e fornece o número como saída.
O motivo pelo qual o Fractran é Turing-complete é porque simula uma máquina de registro. A fatoração primária do número armazena o conteúdo dos registros, enquanto a divisão e multiplicação é uma maneira de adicionar e subtrair condicionalmente os registros. Eu recomendaria a leitura do artigo da Wikipedia (link acima).
O desafio
Sua tarefa é escrever o programa mais curto possível que possa pegar um programa Fractran válido do STDIN como sua única entrada e gerar um programa BF válido para o STDOUT que simule o programa Fractran. Existem duas maneiras de simular um programa Fractran com o BF.
NOTA: Sua resposta não é um programa BF. Sua resposta é o código que gera o programa BF a partir de qualquer programa Fractran. O objetivo é fazer com que o programa BF seja o equivalente ao programa Fractran. (tecnicamente você poderia fazer a competição em BF, mas seria difícil)
Opção 1
Seu programa deve gerar um programa BF que faça o seguinte:
- Toma exatamente 1 número de STDIN na forma do caractere ASCII correspondente (devido à maneira como a entrada BF funciona), que é a entrada para o programa Fractran.
- Imprime exatamente 1 número para STDOUT na forma do caractere ASCII correspondente, que é a saída do programa Fractran.
Esta opção pretende representar a entrada e a saída exatas de uma máquina virtual Fractran.
opção 2
O código BF que seu programa produz deve fazer o seguinte:
- Tome a entrada tendo a fatoração principal do número já codificado na memória (antes da execução do programa). Se a entrada for 28 (2 * 2 * 7), haverá um valor 2 na segunda célula e um valor 1 na sétima célula (o ponteiro inicia na célula 0). Todas as outras células serão zero.
- Forneça saída tendo a fatoração principal da saída codificada na memória quando o programa terminar. Se a saída for 10, deve haver um valor de 1 em cada uma das células 2 e 5. Todas as outras células com números primos devem ter um valor zero. O conteúdo de outras células não importa.
Esta opção representa o modelo de computação por trás da linguagem Fractran.
Regras e Requisitos
- Entrada (no topo do seu programa) será uma lista de frações no STDIN. Haverá uma fração por linha com uma vírgula entre o numerador e o denominador. Uma linha vazia representa o fim da entrada. As frações sempre serão reduzidas aos termos mais baixos.
- A saída do seu programa deve ser um programa BF válido de linha única para STDOUT. Este programa deve poder simular esse programa Fractran específico de acordo com uma das duas opções. Para qualquer entrada, o programa BF gerado deve ser capaz de produzir a mesma saída que o programa Fractran.
- Você deve indicar qual opção você escolheu.
- Você pode escolher os limites na memória e na fita BF e se eles estão quebrando
- CÓDIGO GOLFE. Além disso, o tamanho dos programas BF emitidos não importa, apenas o tamanho do programa que está fazendo a conversão.
- Os programas devem consistir apenas em ASCII imprimível
Se eu sou ambíguo em qualquer lugar, não hesite em perguntar. Este é um desafio muito complicado de descrever.
Além disso, publique o código BF gerado pelo seu programa para a seguinte entrada, para fornecer uma maneira fácil de verificar se o seu programa está funcionando:
33,20
5,11
13,10
1,5
2,3
10,7
7,2
Este programa calcula o número de 1s na expansão binária de um número. No entanto, a entrada e a saída são formatadas de maneira estranha (como em todos os programas Fractran). A entrada é do formato 2 ^ A, enquanto a saída é do formato 13 ^ B.
fonte
Respostas:
Python, 182 caracteres
Opção 1, células de bytes padrão. Existem apenas 255 entradas possíveis (0 como uma entrada realmente não faz sentido), então eu apenas corro um intérprete Fractran 255 vezes em Python e giro um programa Brainfuck simples de pesquisa de tabela que codifica os resultados.
Saída para a entrada de exemplo (
___
= mais 246 condições aninhadas, não consigo colar o resultado inteiro, pois ele é muito grande):fonte
Python, 420 caracteres
Isso usa uma espécie de combinação das opções 1 e 2: pressupõe que o cérebro seja implementado com números inteiros grandes (eu uso uma implementação Sage). Insira um programa fractran, por exemplo
33/20,5/11,13/10,1/5,2/3,10/7,7/2
,. Em seguida, pré-carregue um número, por exemplo,2^5
, no cursor. Em seguida, execute a saída desse script python. Aguarde 44 segundos. O resultado13^2
fica onde o cursor começou. Não esperei pela resposta2^7
.Este é o meu primeiro script de foda cerebral. Certamente pode ser ainda mais jogado, mas tenho outras coisas para fazer até mais tarde esta noite.
edit: em vez de jogar golfe ainda mais, estou trabalhando em uma solução para a opção 2. Além disso, aqui está a saída do programa solicitado:
fonte
2^7
com o meu intérprete Brainfuck em menos de 5 segundos. Além disso, não deveria ser emraw_input()
vez deraw_input
(ou é alguma peculiaridade que eu não conheço)?raw_input()
é necessário. Não estou surpreso que intérpretes competentes de cérebro fiquem melhor do que minha implementação ingênua e terrível do Sage.Perl, 326 caracteres
Espero responder minha própria pergunta, estimulando mais respostas. É claro que não sou elegível para ganhar. Esta é a opção 2 com memória e células ilimitadas, embora funcione na quebra de células. Cada fração é convertida em um único bloco de código. As novas linhas são para facilitar a leitura.
Aqui está o exemplo de saída. Isso tira proveito do fato de que outros caracteres são ignorados como comentários. Também parece ser uma saída muito curta em comparação com as outras entradas, embora o tamanho da saída não seja tecnicamente importante.
fonte
Sábio, 431 caracteres
Esta é uma solução completamente nova. Eu descobri algumas maneiras melhores de fazer as coisas no cérebro, e isso implementa corretamente a Opção 2. Novas linhas adicionadas para maior clareza. Provavelmente isso pode ser ainda mais complicado, mas envolve reescrever o BF para ter uma profundidade de loop mais baixa.
Saída de amostra:
Dada a entrada
33/20,5/11,13/10,1/5,2/3,10/7,7/2
fonte