Un contador Geiger es un dispositivo que se usa para detectar radiación.
Haremos un programa de contador Geiger.
Como todos sabemos, cuando la radiación golpea un programa de computadora, elimina exactamente 1 byte al azar. Entonces, un programa contador de Geiger es un programa que en sí mismo no hace nada, pero cuando se elimina cualquier byte, el programa modificado se imprime beep
para indicar la presencia de radiación.
Las respuestas se puntuarán en bytes, siendo menos bytes mejores. Las respuestas deben ser de al menos 1 byte.
Su programa puede imprimir beep
con una nueva línea al final o imprimir una nueva nueva línea para la salida vacía, siempre que lo haga de manera consistente. Su programa también puede utilizar un caso diferente de beep
como BEEP
, bEEP
o Beep
tanto tiempo como lo hace constantemente.
fuente
Respuestas:
Perdido ,
303 293 263 253 238228 bytesPruébalo en línea!
Script de verificación (tomado de la respuesta del usuario 202729 ). Desafortunadamente, esto solo puede probar la mitad del código a la vez, pero puede estar seguro de que he probado todo el programa.
Ouch, esta fue una pregunta difícil. Citaré la respuesta eliminada de WW:
Desafortunadamente, su respuesta no tuvo en cuenta la eliminación de nuevas líneas, lo que arruinó todo.
Explicación:
(tenga en cuenta que algunos bytes pueden estar apagados aquí y allá)
Primero hablemos de la estructura general del código:
Todo menos la línea de procesamiento debe estar completamente compuesto por uno
>
o por uno\/
. ¿Por qué? Bueno, como ejemplo, eliminemos una nueva línea:La primera línea ahora es mucho más larga que el resto del bloque. Si un puntero se generara en un no
>\/
personaje con movimiento vertical, entonces se quedaría atascado en un bucle infinito.La parte más grande del detector de radiación es la sección al final de cada línea.
Normalmente, una IP que pasa por esto desde la primera línea saldría de la última línea. Sin embargo, si se elimina cualquier carácter en la línea, entonces esa línea se desplaza hacia abajo, por ejemplo:
Y, en cambio, la IP sale de la línea a la que le falta un byte (con la excepción de la última línea, donde sale de la penúltima).
A partir de ahí, cada una de las primeras cuatro líneas redirigirá a la segunda línea:
Lo que luego conducirá a cualquiera de las dos
beep
eras.Si alguno de los bytes en el primer
beep
er ha sido eliminado, entonces pasa al segundo:Ambas
beep
ers vuelven a la primera línea y a la terminación@
.Algunas otras partes misceláneas:
Se
(((((([[[[[[[
usa para borrar la pila cuando el puntero comienza dentro de un par de comillas y termina empujando toda la primera línea para apilar. Desafortunadamente, debe ser tan largo porque la primera línea nueva se puede quitar para hacer que la primera línea doble el tamaño. Experimentar generando elbeep
uso de aritmética en lugar de comillas terminó por más tiempo.Los
\
sys/
dispersos a través de las líneas están ahí para los bytes de golf en la línea superior del código al redirigir el puntero a las líneas correctas. Como la mayoría de las líneas de fondo son solo de relleno, solo la línea superior puede jugar al golf. Si alguien tiene alguna idea para una pila más corta a prueba de radiación más clara que la que tengo ahora, siéntase libre de comentar.fuente
\/
de separar losbeep
empujes y el hecho de que solo una de las citas necesitaba una cláusula de salida ayudóHexagonía , 38 bytes.
Pruébalo en línea!
Programa de verificación.
Explicación
Hacemos uso de la autodetección de Hexagony de hexágono de longitud lateral aquí.
Si no se eliminan bytes, el programa tiene una longitud lateral 4 y se ve así:
Sin embargo, si se elimina un byte. Hay 2 casos.
El byte eliminado es después del segundo
<
.El flujo de ejecución sería:
Hay 2 consecutivos
@
en la quinta línea, por lo que incluso si se elimina uno de ellos, la IP golpeará con seguridad a@
.El byte eliminado es igual o anterior al segundo
<
.Luego, la segunda mitad permanecerá intacta y la IP ya no se redirigirá hacia arriba
<
. Imagen del flujo de ejecución:fuente
Hexagonía ,
3429 bytesPruébalo en línea! ¡Verificación!
Explicación:
Aquí está el código normal formateado en un hexágono apropiado usando HexagonyColorer :
El doble
//
al principio asegura que este camino siempre se tome. Si se elimina algún personaje,@
se elimina de la ruta, ya sea desplazándose uno hacia atrás o eliminándose a sí mismo:En este caso, hemos eliminado un carácter después del
|
, lo que hace que siga este camino, imprimiendobeep
:Si, en cambio, eliminamos un carácter anterior a
|
(o al|
propio), seguimos la otra impresora de pitidos:Luego consideramos todas las posibilidades y solo
beep
usamos las partes no irradiadas del programa.fuente
Brainfuck auto modificable ,
7363 bytesPruébalo en línea! ¡Verificación!
Los espacios en el medio del código en realidad representan bytes NUL.
Explicación:
El código se divide en dos secciones por 3 bytes NUL en el medio. Ambos básicamente imprimen
beep
si la otra sección está irradiada (con un par de excepciones).Primero, el
<<[[
principio es asegurar que todos los]
s coincidan en cualquier momento.[
s no intentará buscar una coincidencia]
si la celda es positiva, mientras que]
s sí . Si alguno]
salta de nuevo a uno de estos soportes, generalmente salta hacia atrás de inmediato porque la celda está0
.La siguiente parte,
[[<<]]>
luego verifica si la longitud de la sección 2 es par. Si es así, ejecuta la otra mitad de la sección 1, que imprimebeep
utilizando elbbeepp
al comienzo de la sección 2.Luego borra toda la sección 2 para que no se ejecute.
En la sección 2, verificamos si la longitud de la sección 1 y los bytes NUL es divisible por
3
con+[<<<]>>
.Del mismo modo, imprimimos
beep
.fuente
Z80Golf ,
533634 bytes-16 bytes gracias a @Lynn
-2 bytes gracias a @Neil
Dado que este es solo el código de máquina Z80, hay muchos no imprimibles en este, así que tenga un
xxd -r
hexdump reversible:Pruébalo en línea! (probador exhaustivo en Python)
Explicación
z80golf es la máquina Z80 hipotética de Anarchy Golf, donde
call $8000
es un putchar,call $8003
es un getchar,halt
hace que el intérprete salga, su programa se coloca en$0000
, y toda la otra memoria está llena de ceros. Hacer que los programas sean a prueba de radiación en el ensamblaje es bastante difícil, pero una técnica genéricamente útil es usar instrucciones idempotentes de un byte. Por ejemplo,es solo un byte y
a | c | c == a | c
, por lo tanto, puede hacerse a prueba de radiación simplemente repitiendo las instrucciones. En el Z80, una carga inmediata de 8 bits es de dos bytes (donde el inmediato está en el segundo byte), por lo que también puede cargar algunos valores en registros de manera confiable. Esto es lo que hice originalmente al comienzo del programa, para que pueda analizar las variantes más largas que archivé al final de la respuesta, pero luego me di cuenta de que hay una manera más simple.El programa consta de dos cargas útiles independientes, donde una de ellas podría haber sido dañada por la radiación. Compruebo si se eliminó un byte y si el byte eliminado se encontraba antes de la segunda copia de la carga útil, verificando los valores de algunas direcciones de memoria absolutas.
Primero, debemos salir si no se observó radiación:
Si se eliminó algún byte, todos los bytes se desplazarán y
$0020
contendrán el último76
, por$0021
lo que será un cero. Podemos permitirnos irradiar el comienzo del programa, a pesar de que prácticamente no hay redundancia:$10
se elimina el desplazamiento del salto , se detectará correctamente la radiación, no se tomará el salto y el desplazamiento no importará. El primer byte de la próxima instrucción se consumirá, pero dado que está diseñado para ser resistente a la eliminación de bytes, esto no importa.$20
se elimina el código de operación de salto , el desplazamiento de salto$10
se descodificará comodjnz $ffe4
(consumiendo el siguiente byte de instrucción como el desplazamiento, ver arriba), que es una instrucción de bucle, decremento B, y saltará si el resultado no es cero. Debido a queffe4-ffff
está lleno de cerosnop
, y el contador del programa se ajusta, esto ejecutará el comienzo del programa 256 veces, y finalmente continuará. Estoy sorprendido de que esto funcione.$dd
, el resto del fragmento se decodificará comoor (hl) / ld ($1020), hl
, y luego se deslizará a la siguiente parte del programa. Elor
no va a cambiar cualquier registros importantes, y debido HL es cero en este punto, la escritura también se suprimirá.$b6
resto, el resto se decodificará comold ($1020), ix
y proceda como se indicó anteriormente.$21
hará que el decodificador se coma el$20
, desencadenando eldjnz
comportamiento.Tenga en cuenta que el uso
or a, (ix+*)
ahorra dos bytesld a, (**) / and a / and a
gracias a la verificación integrada de cero.Ahora debemos decidir cuál de las dos copias de la carga útil ejecutar:
Las dos copias están separadas por un nop, ya que se usa un salto relativo para elegir entre ellas, y la radiación podría haber cambiado el programa de una manera que haría que el salto saltara el primer byte después del destino. Además, el nop está codificado como cero, lo que facilita la detección de bytes desplazados. Tenga en cuenta que no importa qué carga útil se elija si el interruptor en sí está dañado, porque ambas copias son seguras. Sin embargo, asegurémonos de que no salte a la memoria no inicializada:
$dd
hará que los siguientes dos bytes se decodifiquen comoor (hl) / dec d
. Clobbers D. No es gran cosa.$b6
creará una codificación más larga no documentada paradec d
. Lo mismo que arriba.$15
leerá en su$28
lugar como el desplazamiento, y la ejecución continuará en el$0c
, como a continuación.$28
desaparece,$0c
se decodifica comoinc c
. La carga útil no le importac
.$0c
: para eso está el nop. De lo contrario, el primer byte de la carga útil se habría leído como el desplazamiento de salto, y el programa saltaría a la memoria no inicializada.La carga útil en sí es bastante simple. Creo que el tamaño pequeño de la cadena hace que este enfoque sea más pequeño que un bucle, y es más fácil hacer que la posición sea independiente de esta manera. El
e
debeep
repeticiones, por lo que se pueden reducir la unold a
. Además, debido a toda la memoria entre$0038
y$8000
se pone a cero, puedo caer a través de él y utilizar un cortorst
variante de lacall
instrucción, que sólo funciona para$0
,$8
,$10
y así sucesivamente, hasta$38
.Enfoques más antiguos
64 bytes
58 bytes
53 bytes
Este tiene una explicación en el historial de edición, pero no es muy diferente.
Qué pasa si: cualquier salida no vacía estaba bien en lugar de pitido
1 byte
halt
s el programa normalmente, pero si la radiación lo elimina, entonces la memoria estará llena de ceros, haciendo$8000
ejecutar un número infinito de veces, imprimiendo muchos bytes nulos.fuente
a
comienza en cero, ¿no puedes usarlo enor a, (N);
lugar deld a, (N); and a;
? Parece que puede guardar un par de bytes de esa manera.or a, (ix + N)
?20 19
al principio se convierta20 18
, y al eliminar el20
crea un salto incondicional hacia atrás, por lo que un nop tiene que agregarse después del primer salto en el programa, invirtiendo el guardado de bytes.> <> , 23 bytes
Pruébalo en línea! Verificación.
Sinceramente, es realmente sorprendente lo corto que obtuve esto. Termina con un error.
Versión sin errores, 29 bytes
Pruébalo en línea!
fuente
Klein , una de cada topología, totalizando 291 bytes
Después de ver la respuesta de WW usando la
001
topología, decidí ver qué difícil sería hacer un contador Geiger para cada topología. (Spoiler: muy difícil. Es difícil saber adónde irá el puntero sin gestos con las manos que me hagan ver que estoy descubriendo qué mano es mi izquierda)¡Verificación!
(También pensé en escribir un programa que sea un contador Geiger válido en todas las topologías, pero que tenga que esperar. Sin embargo, si alguien más quiere intentarlo, estoy ofreciendo una recompensa de 500 repeticiones)
000 y 010, 21 bytes
¡Prueba 000 en línea! y prueba 010 en línea!
Esto es portado desde mi
><>
solución . Obviamente, esto funciona000
, ya que esa es la topología predeterminada para la mayoría de los lenguajes 2D, pero me sorprendió que también funcione010
.001 y 011, 26 bytes
¡Prueba 001 en línea! y prueba 011 en línea!
Este se copia directamente de la respuesta de WW . ¡Gracias!
100, 21 bytes
Pruébalo en línea!
101, 21 bytes
Pruébalo en línea!
110, 26 bytes
Pruébalo en línea!
111, 24 bytes
Pruébalo en línea!
200, 21 bytes
Pruébalo en línea!
201, 31 bytes
Pruébalo en línea!
De lejos, el más molesto.
210, 26 bytes
Pruébalo en línea!
211, 27 bytes
Pruébalo en línea!
El único en el que tuve que manejar entrar en el busca por el lado derecho.
fuente
Brainfuck auto modificable ,
144102 bytesLos no imprimibles se muestran como secuencia de escape (por ejemplo
\x01
).¡Verificación!
fuente
Encantamientos rúnicos , 29 bytes
Pruébalo en línea!
Esencialmente lo mismo que la respuesta Klein 000 o> <> (comencé con la respuesta Klein). El único cambio realmente necesario era convertir la
<
entradaL
y la.
entrada(traducción de símbolos de comando), insertar los puntos de entrada de IP (necesidad 2, de lo contrario, una eliminación daría como resultado un programa que no se compila) y la inserción del
y
comando dela para obtener el dos IP para fusionar (imprimiendo solo unabeep
), nuevamente, necesitando dos También se requiere insertar NOP adicionales para mantener las longitudes de línea iguales. Klein también utiliza convenientemente@
para "imprimir y terminar".No hay capacidad para utilizar el espacio en blanco en la parte inferior izquierda, ya que cualquier reflector para cambiar de dirección inhibe la capacidad de detectar radiación. por ejemplo (26 bytes, irradiado
y
):No imprime ninguna salida, debido a que el segmento de entrada doblado causa un reflejo de regreso al terminador de la línea inferior.
fuente
Befunge-93 , 55 bytes
Pruébalo en línea! ¡Verificación!
Esperaba hacerlo un poco más pequeño que esto, pero la longitud de la
beep
impresora es el cuello de botella.fuente
Wumpus ,
37 34 3231 bytesPruébalo en línea! ¡Verificación!
Esta solución utiliza el hecho de que
.
salta a un módulo de posición a lo largo del programa.Alternativamente para la misma cantidad de bytes
Pruébalo en línea! ¡Verificación!
Éste utiliza la diferencia en la dirección del puntero para longitudes de línea pares e impares. (Realmente no sé cómo funciona el primero
"
cuando se elimina la nueva línea)fuente
Klein (001), 26 bytes
Pruébalo en línea!
¡Verificar!
Explicación
Este programa aprovecha la topología única de Klein, en particular el 001 topología , que es una botella de Klein.
Sin editar, el programa sigue la ruta de ejecución:
Eliminar un byte del programa puede afectar el programa de 4 maneras (cada una en un color diferente):
Lo primero que debe tener en cuenta es que
<<
siempre desviará la ip a la izquierda del origen al comienzo. Si uno de los<
se elimina s, el otro toma su lugar. Entonces, si se elimina algún byte de la sección roja, se seguirá la siguiente ruta de ejecución:Si se elimina el byte azul, obtenemos la ruta muy simple:
Si se elimina la nueva línea, obtenemos la ruta:
El camino amarillo es un poco más complejo. Como la línea inferior es una más larga que la línea superior, cuando el programa se cuadra al comienzo de la ejecución, se agrega un carácter virtual al final de la primera línea para que tengan el mismo tamaño. Si se elimina algún byte en la segunda línea, la línea se acorta y ese carácter virtual no se agrega. Esto es importante porque
!
normalmente salta sobre el personaje virtual, pero en su defecto, salta sobre él/
.fuente
><>
solución000
por 21 bytesRevés ,
2521 bytesPruébalo en línea! ¡Verificación!
Esto utiliza la capacidad de Backhand para cambiar el valor del paso del puntero para omitir una instrucción en cada paso y resolver el problema de redundancia. Luego utiliza el
j
comando para verificar si el código se irradia saltando al último carácter (@
, detener) si no, y saltando al segundo último (H
, detener y apilar salida) si es así.fuente