Um contador Geiger é um dispositivo usado para detectar radiação.
Faremos um programa de contador Geiger.
Como todos sabemos, quando a radiação atinge um programa de computador, ela remove exatamente 1 byte aleatoriamente. Portanto, um programa de contador Geiger é um programa que não faz nada, mas quando qualquer byte é removido, o programa modificado é impresso beep
, para indicar a presença de radiação.
As respostas serão pontuadas em bytes, com menos bytes sendo melhores. As respostas devem ter pelo menos 1 byte.
Seu programa pode imprimir beep
com uma linha nova à direita ou uma nova linha para saída vazia, desde que seja consistente. Seu programa também pode usar um caso diferente para beep
tais como BEEP
, bEEP
ou Beep
tanto tempo como ele faz isso de forma consistente.
fonte
Respostas:
Perdido ,
303 293 263 253 238228 bytesExperimente online!
Script de verificação (emprestado da resposta do usuário 202729 ). Infelizmente, isso só pode testar metade do código de cada vez, mas tenha certeza de que testei o programa inteiro.
Ai, essa foi difícil. Vou citar a resposta excluída da WW:
Infelizmente, sua resposta não levou em consideração a remoção de novas linhas, o que estragou tudo.
Explicação:
(observe que alguns bytes podem estar desativados aqui e ali)
Primeiro vamos falar sobre a estrutura geral do código:
Tudo, exceto a linha de processamento, deve ser inteiramente composto por um
>
ou um dos\/
. Por quê? Bem, como exemplo, vamos remover uma nova linha:A primeira linha agora é muito mais longa que o resto do bloco. Se um ponteiro aparecer em um não
>\/
caractere com movimento vertical, ele ficará preso em um loop infinito.A maior parte do detector de radiação é a seção no final de cada linha.
Normalmente, um IP que passa por isso da primeira linha sai da última linha. No entanto, se algum caractere da linha for removido, essa linha mudará para um, por exemplo:
E, em vez disso, o IP sai da linha que está faltando um byte (com exceção da última linha, onde sai do penúltimo para o último).
A partir daí, cada uma das quatro primeiras linhas será redirecionada para a segunda linha:
O que levará a um dos dois
beep
.Se algum dos bytes no primeiro
beep
er foi removido, ele passa para o segundo:Os dois
beep
então retornam à primeira linha e ao término@
.Algumas outras partes diversas:
O
(((((([[[[[[[
é usado para limpar a pilha quando o ponteiro começa dentro de um par de aspas e acaba empurrando a primeira linha inteira para empilhar. Infelizmente, isso deve ser longo, porque a primeira nova linha pode ser removida para tornar a primeira linha duas vezes maior. A experiência de gerar abeep
aritmética de uso em vez de aspas acabou por mais tempo.Os
\
s e/
s espalhados pelas linhas existem para bytes de golfe na linha superior do código, redirecionando o ponteiro para as linhas corretas. Como a maioria das linhas de fundo é apenas de preenchimento, apenas a linha de cima pode ser jogada no golfe. Se alguém tiver alguma idéia para uma pilha mais curta à prova de radiação, mais clara do que eu tenho agora, fique à vontade para comentar.fonte
\/
separar osbeep
empurra e o fato de que apenas uma das citações necessária uma cláusula de saída ajudouHexagonia , 38 bytes
Experimente online!
Programa de verificação.
Explicação
Utilizamos a detecção automática de hexágonos do comprimento lateral do hexágono aqui.
Se nenhum bytes for removido, o programa terá o comprimento lateral 4 e terá a seguinte aparência:
Se, no entanto, um byte é removido. Existem 2 casos.
O byte removido é após o segundo
<
.O fluxo de execução seria:
Existem 2 consecutivas
@
na 5ª linha; portanto, mesmo se uma delas for removida, o IP atingirá com segurança a@
.O byte removido é igual ou antes do segundo
<
.Em seguida, a segunda metade permanecerá intacta, e o IP não será mais redirecionado para cima por isso
<
. Imagem do fluxo de execução:fonte
Hexagonia ,
3429 bytesExperimente online! Verificação!
Explicação:
Aqui está o código normal formatado em um hexágono apropriado usando HexagonyColorer :
A duplicação
//
no início garante que esse caminho seja sempre seguido. Se qualquer caractere for removido, ele@
será removido do caminho, sendo movido um para trás ou sendo removido:Nesse caso, removemos um caractere após o
|
, o que o faz seguir esse caminho, imprimindobeep
:Se, em vez disso, removermos um caractere antes do
|
(ou do|
próprio), seguiremos a outra impressora de bipes:Contamos com todas as possibilidades e usamos apenas
beep
as partes não irradiadas do programa.fonte
Brainfuck auto-modificável ,
7363 bytesExperimente online! Verificação!
Os espaços no meio do código estão realmente representando NUL bytes.
Explicação:
O código é dividido em duas seções por 3 NUL bytes no meio. Ambos basicamente imprimem
beep
se a outra seção for irradiada (com algumas exceções).Primeiro, o
<<[[
princípio é garantir que todos os]
s sejam correspondidos a qualquer momento.[
s não tentará procurar uma correspondência]
se a célula for positiva, enquanto]
s o fazem . Se algum]
pular de volta para um desses colchetes, ele geralmente volta imediatamente porque a célula está0
.A próxima parte,
[[<<]]>
depois verifica se o comprimento da seção 2 é uniforme. Nesse caso, ele executa a outra metade da seção 1, que é impressabeep
usando obbeepp
no início da seção 2.Em seguida, limpa toda a seção 2 para que não seja executada.
Na seção 2, verificamos se o comprimento da seção 1 e os bytes NUL são divisíveis por
3
com+[<<<]>>
.Da mesma forma, imprimimos
beep
.fonte
Z80Golf ,
533634 bytes-16 bytes graças a @Lynn
-2 bytes graças a @Neil
Como este é apenas o código de máquina Z80, há muitos imprimíveis neste, portanto, tenha um
xxd -r
hexdump -reversible:Experimente online! (testador exaustivo em Python)
Explicação
z80golf é a hipotética máquina Z80 da Anarchy Golf, onde
call $8000
é um putchar,call $8003
é um getchar,halt
faz com que o intérprete saia, seu programa é colocado$0000
e todas as outras memórias são preenchidas com zeros. Tornar os programas à prova de radiação na montagem é bastante difícil, mas uma técnica genericamente útil é usar instruções idempotentes de um byte. Por exemplo,é apenas um byte e
a | c | c == a | c
, portanto, pode ser protegido contra radiação apenas repetindo a instrução. No Z80, uma carga imediata de 8 bits é de dois bytes (onde a imediata está no segundo byte), portanto, você também pode carregar alguns valores nos registros de maneira confiável. Foi o que fiz originalmente no início do programa, para que você possa analisar as variantes mais longas que arquivei na parte inferior da resposta, mas depois percebi que existe uma maneira mais simples.O programa consiste em duas cargas independentes, onde uma delas pode ter sido danificada pela radiação. Verifico se um byte foi removido e se o byte removido foi anterior à segunda cópia da carga, verificando os valores de alguns endereços de memória absolutos.
Primeiro, precisamos sair se nenhuma radiação for observada:
Se algum byte foi removido, todos os bytes serão alterados e
$0020
conterão o último76
, assim$0021
será um zero. Podemos nos dar ao luxo de irradiar o início do programa, mesmo que não haja praticamente redundância:$10
for removido, a radiação será detectada corretamente, o salto não será realizado e o deslocamento não será importante. O primeiro byte da próxima instrução será consumido, mas como ele foi projetado para resistir à remoção de bytes, isso não importa.$20
for removido, o deslocamento do salto$10
será decodificado comodjnz $ffe4
(consumindo o próximo byte de instrução como o deslocamento - veja acima), que é uma instrução de loop - decremento B, e saltará se o resultado não for zero. Comoffe4-ffff
é preenchido com zerosnop
, o contador do programa é executado, isso executará o início do programa 256 vezes e, finalmente, continuará. Estou surpreso que isso funcione.$dd
fará com que o restante do trecho decodifique comoor (hl) / ld ($1020), hl
e deslize para a próxima parte do programa. Aor
não mudará nenhum registros importantes, e porque HL é zero neste ponto, a gravação também vai cancelar.$b6
decodificador fará com que o restante decodifiqueld ($1020), ix
e prossiga como acima.$21
fará com que o decodificador coma$20
, desencadeando odjnz
comportamento.Observe que o uso
or a, (ix+*)
economiza dois bytes,ld a, (**) / and a / and a
graças à verificação integrada de zero.Agora precisamos decidir qual das duas cópias da carga útil executar:
As duas cópias são separadas por um nop, pois é usado um salto relativo para escolher entre elas, e a radiação poderia ter mudado o programa de uma maneira que faria o salto pular o primeiro byte após o destino. Além disso, o nop é codificado como zero, o que facilita a detecção de bytes deslocados. Observe que não importa qual carga útil é escolhida se o switch estiver corrompido, porque as duas cópias estarão seguras. Vamos garantir que ele não entre na memória não inicializada:
$dd
fará com que os próximos dois bytes decodifiquem comoor (hl) / dec d
. Clobbers D. Não é grande coisa.$b6
criará uma codificação mais longa não documentada paradec d
. O mesmo que acima.$15
lerá o$28
deslocamento como deslocamento e a execução prosseguirá no$0c
, como abaixo.$28
desaparece, o$0c
é decodificado comoinc c
. A carga útil não se importac
.$0c
- é para isso que serve o nop. Caso contrário, o primeiro byte da carga útil teria sido lido como deslocamento de salto e o programa entraria na memória não inicializada.A carga útil em si é bem simples. Eu acho que o tamanho pequeno da string torna essa abordagem menor que um loop, e é mais fácil tornar a posição independente dessa maneira. O
e
in sebeep
repete, para que eu possa raspar umld a
. Também, porque toda a memória entre$0038
e$8000
é zerado, eu posso cair através dele e usar um mais curtorst
variante dacall
instrução, que só funciona para$0
,$8
,$10
e assim por diante, até$38
.Abordagens mais antigas
64 bytes
58 bytes
53 bytes
Este tem uma explicação no histórico de edições, mas não é muito diferente.
E se: qualquer saída não vazia foi boa em vez de emitir um sinal sonoro
1 byte
halt
é o programa normalmente, mas se a radiação o remover, a memória estará cheia de zeros, fazendo$8000
executar um número infinito de vezes, imprimindo muitos bytes nulos.fonte
a
começa em zero, você não pode usar emor a, (N);
vez deld a, (N); and a;
? Parece que você pode salvar alguns bytes dessa maneira.or a, (ix + N)
?20 19
o início se torne20 18
, e remover o20
cria um salto incondicional para trás; nop deve ser adicionado após o primeiro salto no programa, revertendo o byte save.> <> , 23 bytes
Experimente online! Verificação.
Honestamente, é realmente surpreendente o quão curto eu consegui isso. Termina com um erro.
Versão sem erros, 29 bytes
Experimente online!
fonte
Klein , um de cada topologia, totalizando 291 bytes
Depois de ver a resposta da WW usando a
001
topologia, decidi ver como seria difícil criar um contador Geiger para cada topologia. (Spoiler: muito difícil. É difícil descobrir para onde o ponteiro vai sem gestos que me fazem parecer que estou descobrindo qual mão é a minha esquerda)Verificação!
(Também pensei em escrever um programa que seja um contador Geiger válido em todas as topologias, mas isso pode ter que esperar. Se mais alguém quiser tentar, estou oferecendo uma recompensa de 500 representantes)
000 e 010, 21 bytes
Experimente 000 online! e tente 010 online!
Isso é portado da minha
><>
solução . Obviamente, isso funciona000
, já que essa é a topologia padrão para a maioria das linguagens 2D, mas fiquei surpreso que ela também funcione010
.001 e 011, 26 bytes
Experimente o 001 online! e tente 011 online!
Este é copiado diretamente da resposta da WW . Obrigado!
100, 21 bytes
Experimente online!
101, 21 bytes
Experimente online!
110, 26 bytes
Experimente online!
111, 24 bytes
Experimente online!
200, 21 bytes
Experimente online!
201, 31 bytes
Experimente online!
De longe, o mais chato.
210, 26 bytes
Experimente online!
211, 27 bytes
Experimente online!
O único onde eu tinha que lidar ao entrar no bipe pelo lado direito.
fonte
Brainfuck auto-modificável ,
144102 bytesNão imprimíveis são exibidos como sequência de escape (por exemplo
\x01
).Verificação!
fonte
Encantos Rúnicos , 29 bytes
Experimente online!
Essencialmente o mesmo que a resposta Klein 000 ou> <> resposta (comecei com a resposta Klein). A única mudança realmente necessária foi transformar o
<
intoL
e.
into(tradução dos símbolos de comando), inserir os pontos de entrada IP (necessidade 2, caso contrário, uma exclusão resultaria em um programa não-compilável) e a inserção do
y
comando dela para obter o dois IPs para mesclar (imprimindo apenas umbeep
), novamente, precisando de dois. Também é necessário inserir NOPs adicionais para manter os comprimentos das linhas iguais. Klein também usa convenientemente@
para "imprimir e finalizar".Nenhuma capacidade de utilizar o espaço em branco no canto inferior esquerdo, pois qualquer refletor para mudar de direção inibe a capacidade de detectar radiação. por exemplo (26 bytes, irradiado
y
):Não imprime saída, devido ao segmento de entrada dobrado, causando uma nova reflexão no terminador da linha inferior.
fonte
Befunge-93 , 55 bytes
Experimente online! Verificação!
Eu esperava que fosse um pouco menor que isso, mas o comprimento da
beep
impressora é o gargalo.fonte
Wumpus ,
37 34 3231 bytesExperimente online! Verificação!
Esta solução usa o fato de que
.
salta para um módulo de posição a duração do programa.Como alternativa para a mesma quantidade de bytes
Experimente online! Verificação!
Este utiliza a diferença na direção do ponteiro para comprimentos de linhas pares e ímpares. (Eu realmente não sei como o primeiro
"
realmente funciona quando a nova linha é removida)fonte
Klein (001), 26 bytes
Experimente online!
Verificar!
Explicação
Este programa aproveita a topologia exclusiva da Klein, em particular a topologia 001 , que é uma garrafa Klein.
Não editado, o programa segue o caminho da execução:
A remoção de um byte do programa pode afetá-lo de 4 maneiras (cada uma em uma cor diferente):
A primeira coisa a notar é que
<<
sempre desviará o ip à esquerda da origem no início. Se um dos<
s é excluído, o outro substitui. Portanto, se algum byte for removido da seção vermelha, o seguinte caminho de execução será seguido:Se o byte azul for removido, obtemos o caminho muito simples:
Se a nova linha for removida, obtemos o caminho:
O caminho amarelo é um pouco mais complexo. Como a linha inferior é uma mais longa que a linha superior, quando o programa é elevado ao quadrado no início da execução, um caractere virtual é adicionado ao final da primeira linha para torná-los do mesmo tamanho. Se qualquer byte na segunda linha for removido, a linha será reduzida e esse caractere virtual não será adicionado. Isso é importante porque
!
normalmente salta sobre o personagem virtual, mas, na sua ausência, salta sobre/
ele.fonte
><>
solução000
para 21 bytesBackhand ,
2521 bytesExperimente online! Verificação!
Isso usa a capacidade do Backhand de alterar o valor da etapa do ponteiro para ignorar uma instrução a cada etapa e resolver com perfeição o problema de redunância. Ele então usa o
j
comando para verificar se o código é irradiado, saltando para o último caractere (@
, halt), se não, e saltando para o segundo último (H
, halt e pilha de saída), se houver.fonte