Nota: Este desafio permite apenas respostas em idiomas compilados
Tarefa
Sua tarefa é bem simples: crie dois programas diferentes que, quando compilados, resultam na mesma saída.
Pontuação
Aqui é onde entra a diversão. Sua pontuação será o número de bytes únicos presentes em exatamente um programa. Por exemplo, se seus dois programas (codificados na página de códigos IBM 437 ) forem
☻☻Program A
e
☺Program B
Os caracteres que estão em exatamente um programa são
☻☺AB
Portanto, a pontuação é 4. Observe que ☻
aparece duas vezes no primeiro programa, mas é contado apenas uma vez.
Seu objetivo é obter a maior pontuação possível, a maior possível é 256.
Aqui está um programa de pontuação que funciona para programas codificados em ASCII.
Estipulações
Cada byte nos dois programas deve poder ser substituído por um byte diferente, fazendo com que o programa seja compilado em um resultado diferente ou falhe ao compilar todos juntos. A remoção de qualquer byte deve fazer o mesmo.
Você pode usar qualquer sinalizador de compilação, desde que ambos os programas sejam executados com os mesmos sinalizadores.
A compilação resultante deve ser estática (ou seja, não deve variar de uma corrida para outra), se os resultados variarem de máquina para máquina, indicar a máquina na qual ela se destina a funcionar.
A saída da compilação deve ser byte para byte idêntico, não "equivalente" ou "semelhante o suficiente".
A saída da compilação não deve estar vazia
Avisos / Erros não precisam ser os mesmos entre compilações
Se os programas ou a compilação incluírem caracteres não imprimíveis, inclua um hexdump. Embora não seja tecnicamente necessário.
fonte
abcdefghijqlmnop...
para usar mais de 20 caracteres únicos. Isso é permitido?Code-Bowling
pergunta!Respostas:
Perl, pontuação 254 + 2 = 256
Aqui está um dump hexadecimal de um programa:
e aqui está o outro programa:
Perl normalmente não é pensado em uma linguagem compilada, mas é; primeiro é compilado no bytecode e, em seguida, o bytecode é executado. Você pode aplicar um filtro no bytecode (por exemplo, despejá-lo em vez de executar o programa) usando a
-MO
opção Ambos os programas são compilados no seguinte bytecode (desmontado usando-MO=Terse
):Explicação
O Perl substitui todas as instruções sem efeito (como literais de string por conta própria) por uma instrução "instrução sem efeito" codificada no código de código resultante, para que ambos os programas sejam compilados da mesma maneira. Em termos de substituição de caracteres, a substituição da maioria dos caracteres do programa 1 por apóstrofos fará com que ele falhe na compilação (ou substituição dos apóstrofos por
0
). No programa 2, a substituição de qualquer caractere porc
fará com que o programa falhe na compilação (conforme\c
requer um argumento).Quanto às exclusões de caracteres, a primeira versão desta resposta é anterior à "regra de proteção contra radiação" (que excluir qualquer caractere deve alterar o comportamento do programa). Esta versão atualizada, reforçada por radiação, funciona através do uso de uma soma de verificação; se a exclusão de um caractere não causar um erro de sintaxe, o código será compilado em uma chamada para a função inexistente
x
. O compilador Perl não otimiza a chamada no caso em que é feita (e, em geral, não parece ciente de que a função não existe) e, portanto, a saída é diferente. No entanto, a pasta constante do Perl é capaz de ver que o programa não mutado é uma única instrução sem efeito e, portanto, otimiza tudo em uma única instrução como antes.Originalmente, interpretei mal a pergunta como contando apenas caracteres únicos de um programa e tentei otimizar isso. Claramente, o programa 2 precisa conter pelo menos um caractere para gerar o código de operação "instrução sem efeito", o que significa que a melhor pontuação possível em um programa é 255. Ainda não encontrei uma maneira de incluir uma barra invertida no programa 1 de maneira que o personagem imediatamente a seguir não possa ser substituído de forma a interromper o programa, mas não me surpreenderia se fosse possível (levando a uma pontuação de 255 + 1 = 256 )
fonte
C, 231
Programa A
Muitos imprimíveis acima. Aqui está o hexdump do xxd:
Programa B
Eles são compilados com precisão para o mesmo código de objeto. O GCC incorpora o nome do arquivo no código do objeto, portanto, você precisará atribuir aos arquivos o mesmo nome (em diretórios diferentes).
Eu estava preocupado que o fato de não haver referências
i
poderia fazer com que o compilador otimizasse completamente essa variável, mas acho que isso torna uma garantia global de que ela estará presente no objeto. Isso pode ser verificado pela inspeção do conjunto gerado:Observe que no programa B, (a maioria dos) os valores de caracteres são dados em octal. Eles também poderiam ter sido dados em decimal, mas usando octal, ganhamos alguns caracteres extras -
8
e9
- no conjunto de diferenças.O GCC não parece gostar de caracteres CR, LF e (por razões óbvias) NUL dentro de aspas simples
''
.Experimente online e marque .
fonte
char
vez de implícitaint
, em detrimento da pontuação.Python, pontuação
16262728Caracteres únicos:
-+;132547698<ACBEDFOXabopsx|
Calcular a pontuação
Programa 1:
No programa 1, existem 5 espaços na linha aparentemente em branco.
Programa 2:
Foi encontrada alguma ajuda com o código-fonte do otimizador de olho mágico .
Testado com este script auxiliar: Experimente online!
fonte
Python 3.6,
2 3 56Programa 1:
Programa 2:
O Python normalmente não é compilado, mas compila seu código-fonte em arquivos pyc. Fundamentalmente, essa compilação inclui um passe de otimização que muda "1111 + 4168" para 5279. Os sublinhados servem a dois propósitos: um deles é adicionar um à pontuação e o outro é manter o comprimento, que é armazenado no pyc cabeçalho o mesmo. Todas as atribuições de variáveis, exceto 'x', devem manter a
co_consts
ordem correta. Ox*x
no final serve para manterco_stacksize
o mesmo.fonte
compile
função interna, que não adiciona o cabeçalho. só se aplicam ao cabeçalhoos.utime
funçãoFASM, 254
0x00 e 0x1A porque o fasm não suporta os dois símbolos
fonte