Le célèbre webcomic Homestuck utilise un langage de programmation appelé ~ATH
à détruire les univers. Bien que ce défi de golf de code ne soit pas d'écrire un programme pour anéantir notre existence, nous allons détruire des entités plus apprivoisées (bien que moins intéressantes): les variables .
~ATH
(prononcé "jusqu'à la mort", remarquez comment ~ath
est "tilde ath") fonctionne en créant une variable appelée THIS
, en exécutant une commande avec EXECUTE
et en terminant le programme avec THIS.DIE()
. Une page wiki pour l'utilisation de la langue dans Homestuck peut être trouvée ici . L'objectif de ce défi sera de créer un ~ATH
interprète.
Pour relever le défi, je vais créer des détails ~ATH
qui n'existent pas vraiment mais les rendre (quelque peu) utiles.
- Le langage ne fonctionnera qu'avec des entiers, qui sont déclarés avec
import <variable name>;
. La variable sera automatiquement définie sur une valeur de 0. Une seule variable à la fois peut être importée. - Une variable
x
peut être copiée en écriturebifurcate x[y,z];
, ce qui supprimera la variablex
et la remplacera par des variables identiquesy
etz
. Notez qu'il ne peut pas créer une variable avec le même nom que celui supprimé. Essentiellement, une variable est renommée, puis une copie de la variable avec un nom différent est créée. Cela semble être une caractéristique stupide, mais la bêtise est très profondément ancrée dans Homestuck. - La syntaxe pour écrire un programme qui exécute du code
x
est~ATH(x){EXECUTE(<code>)}
. Si vous voulez exécuter du code sur deux variables simultanément, le code devient imbriqué, comme ceci:~ATH(x){~ATH(y){EXECUTE(<code>)}}
. Toutes les commandes de<code>
seront exécutées surx
ety
. - Passons maintenant aux commandes.
+
incrémente les variables pertinentes de 1 et les-
diminue de 1. Et ... c'est tout. - La dernière caractéristique
~ATH
est qu'il tue tout ce avec quoi il fonctionne. Les variables sont imprimées au format<name>=<value>
(suivi d'une nouvelle ligne) à la commande[<name>].DIE();
. Ensuite, le programme imprime le motDIE <name>
et une nouvelle ligne un nombre de fois égal à la valeur absolue de la valeur de la variable. Lorsque des variables sont supprimées simultanément avec[<name1>,<name2>].DIE();
(vous pouvez supprimer autant de variables que vous le souhaitez, tant qu'elles existent), laDIE()
commande est exécutée de manière séquentielle sur les variables.
Exemples de programmes
Programme 1:
import sollux; //calls variable "sollux"
import eridan; //calls variable "eridan"
~ATH(sollux){EXECUTE(--)} //sets the value of "sollux" to -2
~ATH(eridan){EXECUTE(+++++)} //sets the value of "eridan" to 5
[sollux].DIE(); //kills "sollux", prints "DIE sollux" twice
~ATH(eridan){EXECUTE(+)} //sets the value of "eridan" to 6
[eridan].DIE(); //kills "eridan", prints "DIE eridan" 6 times
Production:
sollux=-2
DIE sollux
DIE sollux
eridan=6
DIE eridan
DIE eridan
DIE eridan
DIE eridan
DIE eridan
DIE eridan
Programme 2:
import THIS; //calls variable "THIS"
~ATH(THIS){EXECUTE(++++)} //sets the value of "THIS" to 4
bifurcate THIS[THIS1,THIS2]; //deletes "THIS", creates variables "THIS1" and "THIS2" both equal to 4
~ATH(THIS1){EXECUTE(++)} //sets the value of "THIS1" to 6
[THIS1,THIS2].DIE(); //kills "THIS1" and "THIS2", prints "DIE THIS1" 6 times then "DIE THIS2" 4 times
import THAT; //calls variable "THAT"
bifurcate THAT[THESE,THOSE]; //deletes "THAT", creates variables "THESE" and "THOSE"
~ATH(THESE){~ATH(THOSE){EXECUTE(+++)}EXECUTE(++)} //sets the value of "THESE" and "THOSE" to 3, then sets the value of "THESE" to 5
[THESE,THOSE].DIE(); //kills "THESE" and "THOSE", prints "DIE THESE" 5 times then "DIE THOSE" 3 times
Production:
THIS1=6
DIE THIS1
DIE THIS1
DIE THIS1
DIE THIS1
DIE THIS1
DIE THIS1
THIS2=4
DIE THIS2
DIE THIS2
DIE THIS2
DIE THIS2
THESE=5
DIE THESE
DIE THESE
DIE THESE
DIE THESE
DIE THESE
THOSE=3
DIE THOSE
DIE THOSE
DIE THOSE
C'est du golf de code, donc les règles standard s'appliquent. Le code le plus court en octets gagne.
la source
~ATH
utilise comme virgules fins de ligne pour leimport
,bifurcate
et lesDIE
commandes. REPL et les fichiers sont corrects. La sensibilité à la casse est requise à la fois en entrée et en sortie (j'essaie de faire correspondre le~ATH
plus possible le réel ).Réponses:
Python 2.7.6,
1244130812651253107310721071106510641063 octetsD'accord, je ne bat aucun record ici, mais il s'agit du plus petit Python qui ira dans la mesure où la lecture d'une entrée à la fois à partir d'un fichier plutôt que séquentiellement au fil du temps. J'essaierai de mettre cela à niveau plus tard dans une autre langue (et un interprète, pas seulement un analyseur). Jusque-là, profitez de la monstruosité horriblement horrible.
Remarque : ouvre un fichier appelé
t
dans le répertoire de travail. Pour lui faire ouvrir un argument de ligne de commande, ajoutezimport sys
en haut du fichier et passez't'
àsys.argv[1]
la source
Python 2,
447475463443 octetsIl s'avère que le zip et l'encodage du programme base64 économise toujours des octets sur la version normale. À titre de comparaison, voici la normale:
Fondamentalement, la solution "baguettes magiques regexy" qui était souhaitée. Lit dans le programme entier depuis stdin comme une seule chaîne, remplace les expressions ~ ATH par des expressions Python qui font la sémantique décrite et exécute () la chaîne résultante.
Pour voir ce qu'il fait, regardez le programme python dans lequel le deuxième programme de test fourni est traduit:
C'est une bonne chose que
00 == 0
: PÉvidemment, quelques octets pourraient être économisés en exploitant l'ambiguïté dans les règles. Par exemple, on ne dit pas ce qui devrait arriver si quelqu'un essaie
DIE()
une variable qui n'a pas étéimport
éditée ou qui a déjà étébifurcate
d. Ma conjecture basée sur la description était qu'il devrait y avoir une erreur. Si aucune erreur n'est requise, je pourrais supprimer ladel
déclaration.EDIT: correction d'un bug que les cas de test fournis ne testaient pas. À savoir, tel qu'il était, chaque
~ATH
bloc remettait la variable à zéro avant de l'incrémenter. Cela m'a coûté 28 octets pour résoudre ce problème. Si quelqu'un voit une meilleure façon de remplacer les~ATH
blocs, j'aimerais le savoir.EDIT 2: 12 octets enregistrés en déroulant la boucle d'expression régulière, en les transformant en sous-ensembles et en laissant la compression prendre en charge la répétition.
EDIT 3: économisé 20 octets supplémentaires en remplaçant la
for
boucle interne par une multiplication de chaînes.la source
import sys,re
plutôt queimport sys;import re
python ~ath.py < program.~ath