Un compteur Geiger est un appareil utilisé pour détecter les radiations.
Nous allons créer un programme de compteurs Geiger.
Comme nous le savons tous, lorsque le rayonnement frappe un programme informatique, il supprime exactement 1 octet au hasard. Un programme de compteur Geiger est donc un programme qui lui-même ne fait rien, mais quand un octet est supprimé, le programme modifié s'imprime beep
pour indiquer la présence d'un rayonnement.
Les réponses seront notées en octets avec moins d'octets étant mieux. Les réponses doivent être d'au moins 1 octet.
Votre programme peut imprimer beep
avec une nouvelle ligne à la fin ou imprimer une seule nouvelle ligne pour une sortie vide, tant qu'il le fait de manière cohérente. Votre programme peut également utiliser un cas différent pour par beep
exemple BEEP
, bEEP
ou Beep
tant qu'il le fait toujours.
la source
Réponses:
Perdu ,
303 293 263 253 238228 octetsEssayez-le en ligne!
Script de vérification (emprunté à la réponse de l' utilisateur 202729 ). Malheureusement, cela ne peut tester que la moitié du code à la fois, mais soyez assuré que j'ai testé l'ensemble du programme.
Aïe, c'était difficile. Je vais citer la réponse supprimée de WW:
Malheureusement, sa réponse n'a pas pris en compte la suppression des nouvelles lignes, ce qui a tout gâché.
Explication:
(notez que quelques octets peuvent être affichés ici et là)
Parlons d'abord de la structure générale du code:
Tout sauf la ligne de traitement doit être entièrement composé de l'un
>
ou de l'autre\/
. Pourquoi? Eh bien, à titre d'exemple, supprimons une nouvelle ligne:La première ligne est désormais beaucoup plus longue que le reste du bloc. Si un pointeur devait apparaître sur un non-
>\/
personnage avec un mouvement vertical, il resterait coincé dans une boucle infinie.La plus grande partie du détecteur de rayonnement est la section à la fin de chaque ligne.
Normalement, une adresse IP passant par cette ligne depuis la première ligne quitterait la dernière ligne. Cependant, si un caractère de la ligne est supprimé, alors cette ligne en décale un, par exemple:
Et l'IP à la place quitte la ligne à laquelle il manque un octet (à l'exception de la dernière ligne, où il sort de l'avant-dernier).
De là, chacune des quatre premières lignes sera redirigée vers la deuxième ligne:
Ce qui mènera ensuite à l'un des deux
beep
ers.Si l'un des octets du premier
beep
er a été supprimé, il passe au second:Les deux
beep
ramènent ensuite à la première ligne et à la terminaison@
.Quelques autres pièces diverses:
Le
(((((([[[[[[[
est utilisé pour effacer la pile lorsque le pointeur commence à l'intérieur d'une paire de guillemets et finit par pousser toute la première ligne à s'empiler. Elle doit être si longue malheureusement car la première nouvelle ligne peut être supprimée pour faire la première ligne deux fois la taille. Expérimenter dans la génération de l'beep
arithmétique à l' aide de citations s'est avéré plus long.Les
\
s et/
s dispersés sur les lignes sont là pour les octets de golf dans la ligne de code supérieure en redirigeant le pointeur vers les lignes correctes. Comme la plupart des lignes de fond ne sont que des charges, seule la ligne supérieure peut être jouée au golf. Si quelqu'un a des idées pour une pile anti-rayonnement plus claire, alors ce que j'ai maintenant, n'hésitez pas à commenter.la source
\/
séparation desbeep
poussées et le fait qu'une seule des citations avait besoin d'une clause de sortie ont aidéHexagonie , 38 octets
Essayez-le en ligne!
Programme de vérification.
Explication
Nous utilisons ici l'auto-détection par Hexagony de la longueur des côtés de l'hexagone.
Si aucun octet n'est supprimé, le programme a une longueur de côté 4 et ressemble à ceci:
Si toutefois, un octet est supprimé. Il y a 2 cas.
L'octet supprimé est après le second
<
.Le flux d'exécution serait:
Il y a 2 consécutifs
@
sur la 5ème ligne, donc même si l'un d'eux est supprimé, l'IP frappera en toute sécurité a@
.L'octet supprimé est égal ou supérieur au second
<
.Ensuite, la seconde moitié restera intacte, et l'IP n'est plus redirigée vers le haut par cela
<
. Image du flux d'exécution:la source
Hexagonie ,
3429 octetsEssayez-le en ligne! Vérification!
Explication:
Voici le code normal formaté dans un hexagone approprié en utilisant HexagonyColorer :
Le double
//
au début assure que ce chemin est toujours emprunté. Si un caractère est supprimé, le@
est supprimé du chemin, soit décalé d'un vers l'arrière, soit supprimé lui-même:Dans ce cas, nous avons supprimé un caractère après le
|
, ce qui le fait suivre ce chemin, en imprimantbeep
:Si nous supprimons plutôt un caractère avant
|
(ou le|
lui - même), nous suivons l'autre imprimante de bip:Nous avons ensuite pris en compte toutes les possibilités et nous
beep
n'utilisons que les parties non irradiées du programme.la source
Brainfuck auto-modifiable ,
7363 octetsEssayez-le en ligne! Vérification!
Les espaces au milieu du code représentent en fait des octets NUL.
Explication:
Le code est divisé en deux sections par 3 octets NUL au milieu. Les deux s'impriment essentiellement
beep
si l'autre section est irradiée (à quelques exceptions près).Tout d'abord, le
<<[[
début est de s'assurer que tous les]
s sont appariés à tout moment.[
s ne tentera pas de rechercher une correspondance]
si la cellule est positive, alors que]
s le fait . Si un]
saut revient à l'une de ces parenthèses, il saute généralement immédiatement parce que la cellule l'est0
.La partie suivante,
[[<<]]>
vérifie ensuite si la longueur de la section 2 est paire. Si c'est le cas, il exécute l'autre moitié de la section 1, qui s'imprimebeep
à l'aide debbeepp
au début de la section 2.Il efface ensuite toute la section 2 pour ne pas s'exécuter.
Dans la section 2, nous vérifions si la longueur de la section 1 et les octets NUL est divisible par
3
avec+[<<<]>>
.De même, nous imprimons
beep
.la source
Z80Golf ,
533634 octets-16 octets grâce à @Lynn
-2 octets grâce à @Neil
Comme il ne s'agit que du code machine Z80, il y a beaucoup d'imprimables dans celui-ci, il y a donc un
xxd -r
hexdump réversible:Essayez-le en ligne! (testeur exhaustif en Python)
Explication
z80golf est la machine Z80 hypothétique d'Anarchy Golf, où se
call $8000
trouve un putchar,call $8003
un getchar,halt
fait quitter l'interpréteur, votre programme est placé sur$0000
et toute autre mémoire est remplie de zéros. Rendre les programmes résistants aux radiations dans l'assemblage est assez difficile, mais une technique génériquement utile utilise des instructions idempotentes à un octet. Par exemple,n'est qu'un octet, et
a | c | c == a | c
il peut donc être rendu résistant aux rayonnements en répétant simplement l'instruction. Sur le Z80, une charge immédiate de 8 bits est de deux octets (où l'immédiat se trouve dans le deuxième octet), vous pouvez donc également charger certaines valeurs dans des registres de manière fiable. C'est ce que j'ai fait à l'origine au début du programme, vous pouvez donc analyser les variantes plus longues que j'ai archivées au bas de la réponse, mais j'ai ensuite réalisé qu'il y avait un moyen plus simple.Le programme comprend deux charges utiles indépendantes, dont l'une aurait pu être endommagée par les radiations. Je vérifie si un octet a été supprimé et si l'octet supprimé était avant la deuxième copie de la charge utile, en vérifiant les valeurs de certaines adresses mémoire absolues.
Tout d'abord, nous devons sortir si aucun rayonnement n'a été observé:
Si un octet a été supprimé, tous les octets se déplaceront et
$0020
contiendront le dernier76
, ce$0021
sera donc un zéro. Nous pouvons nous permettre de rayonner le début du programme, même s'il n'y a pratiquement pas de redondance:$10
est supprimé, le rayonnement sera correctement détecté, le saut ne sera pas effectué et le décalage n'aura pas d'importance. Le premier octet de l'instruction suivante sera consommé, mais comme il est conçu pour résister aux suppressions d'octets, cela n'a pas d'importance.$20
est supprimé, alors l'offset de saut$10
sera décodé endjnz $ffe4
(consommant l'octet d'instruction suivant comme offset - voir ci-dessus), qui est une instruction de boucle - décrémenter B, et sauter si le résultat n'est pas nul. Parce qu'ilffe4-ffff
est rempli de zérosnop
et que le compteur de programme se termine, cela exécutera le début du programme 256 fois, puis continuera finalement. Je suis étonné que cela fonctionne.$dd
fera décoder le reste de l'extrait en tant queor (hl) / ld ($1020), hl
, puis se glissera dans la partie suivante du programme. Leor
ne modifiera aucun registre important et, comme HL est nul à ce stade, l'écriture sera également annulée.$b6
fera décoder le reste commeld ($1020), ix
et procéder comme ci-dessus.$21
fera que le décodeur mangera le$20
, déclenchant ledjnz
comportement.Notez que l'utilisation
or a, (ix+*)
économise plus de deux octetsld a, (**) / and a / and a
grâce à la vérification intégrée de zéro.Nous devons maintenant décider laquelle des deux copies de la charge utile exécuter:
Les deux copies sont séparées par un nop, car un saut relatif est utilisé pour choisir entre elles, et le rayonnement aurait pu déplacer le programme d'une manière qui ferait sauter le premier octet après la destination. De plus, le nop est codé comme un zéro, ce qui facilite la détection des octets décalés. Notez que la charge utile choisie n'a pas d'importance si le commutateur lui-même est corrompu, car les deux copies sont alors sûres. Assurons-nous qu'il ne sautera pas dans la mémoire non initialisée, cependant:
$dd
fera décoder les deux octets suivants commeor (hl) / dec d
. Clobbers D. Pas grand-chose.$b6
créera un encodage plus long non documenté pourdec d
. Comme ci-dessus.$15
lira à la$28
place le décalage, et l'exécution se poursuivra au$0c
, comme ci-dessous.$28
disparaît, le$0c
est décodé eninc c
. La charge utile ne se soucie pasc
.$0c
- c'est à cela que sert le nop. Sinon, le premier octet de la charge utile aurait été lu comme décalage de saut et le programme sauterait dans la mémoire non initialisée.La charge utile elle-même est assez simple. Je pense que la petite taille de la chaîne rend cette approche plus petite qu'une boucle, et il est plus facile de rendre la position indépendante de cette façon. Le
e
in sebeep
répète, donc je peux en raser unld a
. En outre, parce que toute la mémoire entre$0038
et$8000
est remis à zéro, je peux tomber à travers et utiliser une plus courterst
variante de l'call
instruction, qui ne fonctionne que pour$0
,$8
,$10
et ainsi de suite, jusqu'à$38
.Approches plus anciennes
64 octets
58 octets
53 octets
Celui-ci a une explication dans l'historique des modifications, mais ce n'est pas trop différent.
Et si: toute sortie non vide était correcte au lieu d'un bip
1 octet
halt
s le programme normalement, mais si le rayonnement le supprime, alors la mémoire sera pleine de zéros, faisant$8000
exécuter un nombre infini de fois, imprimant beaucoup d'octets nuls.la source
a
commence à zéro, ne pouvez-vous pas utiliser à laor a, (N);
place deld a, (N); and a;
? Il semble que vous puissiez enregistrer quelques octets de cette façon.or a, (ix + N)
?20 19
le début devient20 18
, et supprimer le20
crée un saut inconditionnel en arrière, donc un nop doit être ajouté après le premier saut dans le programme, inversant la sauvegarde d'octets.> <> , 23 octets
Essayez-le en ligne! Vérification.
Honnêtement, c'est vraiment surprenant de voir à quel point j'ai obtenu cela. Se termine par une erreur.
Version sans erreur, 29 octets
Essayez-le en ligne!
la source
Klein , une de chaque topologie, totalisant 291 octets
Après avoir vu la réponse de WW utilisant la
001
topologie, j'ai décidé de voir combien il serait difficile de faire un compteur Geiger pour chaque topologie. (Spoiler: très dur. Il est difficile de comprendre où ira le pointeur sans des gestes de la main qui me donnent l'impression de déterminer quelle main est ma gauche)Vérification!
(J'ai également pensé à écrire un programme qui est un compteur Geiger valide sur toutes les topologies, mais qui pourrait devoir attendre. Si quelqu'un d'autre veut essayer, je propose une prime de 500 rep)
000 et 010, 21 octets
Essayez 000 en ligne! et essayez 010 en ligne!
Ceci est porté depuis ma
><>
solution . Cela fonctionne évidemment dans000
, puisque c'est la topologie par défaut pour la plupart des langages 2D, mais j'ai été surpris que cela fonctionne également dans010
.001 et 011, 26 octets
Essayez 001 en ligne! et essayez le 011 en ligne!
Celui-ci est copié directement de la réponse de WW . Merci!
100, 21 octets
Essayez-le en ligne!
101, 21 octets
Essayez-le en ligne!
110, 26 octets
Essayez-le en ligne!
111, 24 octets
Essayez-le en ligne!
200, 21 octets
Essayez-le en ligne!
201, 31 octets
Essayez-le en ligne!
De loin le plus ennuyeux.
210, 26 octets
Essayez-le en ligne!
211, 27 octets
Essayez-le en ligne!
Le seul où j'ai dû gérer l'entrée du signal sonore par le côté droit.
la source
Brainfuck auto-modifiable ,
144102 octetsLes non imprimables sont affichés sous forme de séquence d'échappement (par exemple
\x01
).Vérification!
la source
Enchantements runiques , 29 octets
Essayez-le en ligne!
Essentiellement la même que la réponse Klein 000 ou la réponse> <> (j'ai commencé avec la réponse Klein). Le seul changement vraiment nécessaire était de transformer le
<
enL
et.
en(traduction des symboles de commande), en insérant les points d'entrée IP (besoin 2, sinon une suppression entraînerait un programme non compilable) et l'insertion de la
y
commande dela pour obtenir le deux IP à fusionner (donc une seulebeep
), encore une fois, il en faut deux. Il a également fallu insérer des NOP supplémentaires pour conserver la même longueur de ligne. Klein utilise également commodément@
pour «imprimer et terminer».Aucune capacité à utiliser l'espace blanc en bas à gauche, car tout réflecteur pour changer de direction inhibe la capacité de détecter le rayonnement. par exemple (26 octets, irradiés
y
):N'imprime aucune sortie, car le segment d'entrée plié provoque une ré-réflexion vers le terminateur de la ligne inférieure.
la source
Befunge-93 , 55 octets
Essayez-le en ligne! Vérification!
J'avais espéré le faire un peu plus petit que cela, mais la longueur de l'
beep
imprimante est le goulot d'étranglement.la source
Wumpus ,
37 34 3231 octetsEssayez-le en ligne! Vérification!
Cette solution utilise le fait que
.
saute à un module de position la longueur du programme.Alternativement pour le même nombre d'octets
Essayez-le en ligne! Vérification!
Celui-ci utilise la différence de direction du pointeur pour les longueurs de ligne paires et impaires. (Je ne sais pas vraiment comment fonctionne le premier
"
lorsque la nouvelle ligne est supprimée)la source
Klein (001), 26 octets
Essayez-le en ligne!
Vérifier!
Explication
Ce programme tire parti de la topologie unique de Klein, en particulier la topologie 001 , qui est une bouteille de Klein.
Non modifié, le programme suit le chemin d'exécution:
La suppression d'un octet du programme peut affecter le programme de 4 manières (chacune dans une couleur différente):
La première chose à noter est que
<<
toujours déviera l'ip à gauche de l'origine au début. Si l'un des<
s est supprimé, l'autre prend sa place. Donc, si un octet est supprimé de la section rouge, le chemin d'exécution suivant sera suivi:Si l'octet bleu est supprimé, nous obtenons le chemin très simple:
Si la nouvelle ligne est supprimée, nous obtenons le chemin:
Le chemin jaune est un peu plus complexe. Étant donné que la ligne du bas est plus longue que la ligne du haut, lorsque le programme est mis au carré au début de l'exécution, un caractère virtuel est ajouté à la fin de la première ligne pour leur donner la même taille. Si un octet sur la deuxième ligne est supprimé, la ligne est raccourcie et ce caractère virtuel n'est pas ajouté. Ceci est important car
!
normalement saute par-dessus le personnage virtuel, mais en son absence, il saute à la/
place.la source
><>
solution000
pendant 21 octetsRevers ,
2521 octetsEssayez-le en ligne! Vérification!
Cela utilise la capacité de Backhand à modifier la valeur de l'étape du pointeur pour ignorer une instruction à chaque étape et résoudre soigneusement le problème de redondance. Il utilise ensuite la
j
commande pour vérifier si le code est irradié en sautant au dernier caractère (@
, arrêt) sinon, et en passant à l'avant-dernier (H
, arrêt et pile de sortie) si c'est le cas.la source