Pyth est un langage de golf basé sur Python. Il utilise la notation de préfixe, chaque commande ayant une arité différente (nombre d'arguments qu'elle accepte).
Votre tâche consiste à écrire un vérificateur de syntaxe pour un langage de type Pyth (inexistant), Pith.
Syntaxe de Pith
Pith n'a que 8 commandes à caractère unique:
01234()"
01234
chacun a une arité du nombre correspondant, et donc s'attend à ce que de nombreux arguments après. Par exemple,
400010
est un programme Pith correct car il 4
est suivi de quatre arguments 0
0
0
et 10
le dernier est 1
suivi d'un seul argument 0
. Pour visualiser cela, nous pouvons regarder l'arborescence suivante:
R
|
4
|
-------------
| | | |
0 0 0 1
|
0
où R
est le nœud racine. Une autre façon de penser à cela est que chaque nombre fait référence au nombre d'enfants que le nœud correspondant a dans l'arbre ci-dessus.
Voici un autre programme Pith valide, avec plus d'une commande de base:
210010
correspond à
R
|
-------------
| |
2 1
| |
--------- 0
| |
1 0
|
0
D'autre part,
3120102100
n'est pas un programme Pith correct car l'initiale 3
n'a que deux arguments, que nous pouvons voir en regardant l'arbre ci-dessous:
R
|
3
|
------------------------ ??
| |
1 2
| |
2 ------
| | |
------ 1 0
| | |
0 1 0
|
0
(
Commence ensuite une illimitée, et)
se termine un illimité. Un illimité prend n'importe quel nombre d'arguments (avec avidité) et compte comme un seul argument pour toute commande parent. Toutes les bornes non encore ouvertes à la fin du programme sont automatiquement fermées. Une )
commande n'est pas une erreur si aucune limite n'est ouverte - elle ne fait rien. *
Par exemple, le programme Pith
)31(0)0(201000100
correspond à l'arbre
R
|
3
|
------------------------------
| | |
1 0 (
| |
( -----------------------------
| | | | | |
0 2 0 0 1 0
| |
------- 0
| |
0 1
|
0
Les limites non vides sont correctes, tout ()
comme un programme Pith valide.
Un programme Pith non valide avec un illimité est
12(010
puisque le 2
seul reçoit un argument (le sans limite).
Enfin, "
démarre et termine une chaîne, qui est toujours de 0 arité et compte comme un seul argument, par exemple
2"010""44)()4"
qui est juste un 2
être passé deux arguments de chaîne"010"
et "44)()4"
. Comme les chaînes non liées, les chaînes peuvent également être vides et toutes les chaînes non fermées à la fin du programme sont automatiquement fermées.
* Cette partie est différente de la Pyth originale qui en fait fait faire quelque chose dans un cas comme1)
, mettant fin à la 1-arité et d' élever une erreur.
Entrée sortie
L'entrée sera une seule chaîne non vide composée uniquement des caractères 01234()"
. Vous pouvez éventuellement supposer qu'une nouvelle ligne de fin supplémentaire est toujours présente. Vous pouvez écrire une fonction ou un programme complet pour ce défi.
Vous devez sortir une valeur véridique si l'entrée est Pith syntaxiquement valide, ou une valeur fausse sinon. Les valeurs de vérité et de fausse doivent être fixes, vous ne pouvez donc pas sortir 1
pour un programme valide et2
pour un autre.
Notation
C'est du code-golf, donc le code dans le moins d'octets gagne.
Cas de test
Vérité:
0
)
(
"
()
""
10
400010
210010
("")00
3"""""
(0)))0)1)0
2(2(2(0)0)0)0
2"010""44)()4"
)31(0)0(201000100
())2)1))0"3())"))
3("4321("301(0)21100"4")"123"00)40"121"31000""01010
Faux:
1
1(310
(1)0)
12(010
4"00010"
3120102100
20(2((0)(0)))
2(2(2(0)0)0)01)
4(0102)00)00000
2"00"("00"2(""))
[( [2 [0] [1 [0] ] ] [0] [1 [0]] [0] ]
? Celui que vous avez a des branches de 2, 0, 0, 1 et 0 - le second ne devrait pas être là.())2)1))0"3())"))
(ce qui devrait être vrai, je pense).()210""
avec beaucoup de non-opérations)Réponses:
CJam, 65 octets
Gosh, je souhaite que CJam ait Regex, cela aurait pu être terminé en moins de 50 octets puis
L'idée principale est de continuer à réduire les choses à
0
c'est-10
à- dire à0
,200
à0
et ainsi de suite. Une fois cela fait, nous réduisons tous les crochets correspondants à0
, c'est-()
à- dire à0
,(0)
à0
,(00)
à0
et ainsi de suite. Nous répétons lesL
temps de cycle , oùL
est la longueur d'entrée.La chaîne d'entrée passe initialement par un traitement supplémentaire où nous ajustons pour inégalé
"
et ajoutons beaucoup de)
pour compenser pour inégalé(
Cela garantit qu'après toutes les itérations, il ne reste plus
0
(et pas d'opération)
) dans la chaîne.Mise à jour - correction d'un bug où le
)
non-fonctionnement de niveau supérieur était considéré comme dangereuxExpansion du code
Essayez-le en ligne ici ou exécutez toute la suite
la source
Regex, saveur PCRE, 83 octets
Essayez-le ici.
Regex, saveur PCRE, 85 octets
Essayez-le ici.
Utilisé quelques idées dans la réponse de ce dan1111 .
Quelques explications sur
(?2)*(()(?1))?
.la source
(?2)*(()(?1))?
est la dernière pièce du puzzle que je cherchais. Belle trouvaille! ;)(?2)*(()(?1))?
partie, la(()(?1))?
partie ne correspond à rien, car elle(?2)*
mange déjà tout ce qui(()(?1))?
peut correspondre, et cette construction est utilisée pour définir le groupe de capture 3 lorsque nous entrons(
et désactiver le groupe de capture 3 lorsque nous sommes en dehors de la()
construction (pour permettre la correspondance non apparié)
).lex, 182 octets (157 w / pile de taille fixe)
Ces programmes nécessitent que l'entrée soit une seule chaîne terminée par une nouvelle ligne de caractères valides.
Le programme ci-dessus sera défectueux s'il manque de mémoire, ce qui pourrait théoriquement se produire si vous lui en donnez assez
(
. Mais comme un défaut de segmentation est considéré comme un échec, je le prends pour "falsey", bien que la description du problème ne dise pas quoi faire si les ressources ne suffisent pas.Je l'ai réduit de 157 octets en utilisant simplement une pile de taille fixe, mais cela semblait être de la triche.
Compiler:
Tester:
Sortie de test:
la source
80386 Assembleur, 97 octets
Vidage hexadécimal:
Cela parcourt l'entrée une fois, poussant des nombres supérieurs à zéro sur la pile et les décrémentant lorsqu'un zéro est traité. Les éléments non liés sont traités comme -1.
Prototype de fonction (en C) (la fonction retourne 0 si invalide et 1 si valide):
Assemblage équivalent (NASM):
Le code suivant en C peut être utilisé avec GCC sur un système POSIX pour tester:
la source
Python 2, 353 octets
La fonction d'analyse parcourt les jetons un par un et construit un arbre de la structure du programme. Les programmes non valides déclenchent une exception qui entraîne l'impression d'un zéro (Falsy), sinon une analyse réussie entraîne un un.
La sortie des tests montrant la sortie de l'analyseur:
Le code avant le minifieur:
la source
==
dans les tests - mettre les chaînes en premier signifie que vous pouvez le faireif')'==q
. Je crois que l'une desbreak
déclarations pourrait être remplacée parf=0
, car cela vous permettra également de sortir de lawhile f
boucle. Enfin, au lieu deassert x==y
vous pouvez utiliser1/(x==y)
pour unZeroDivisionError
. ;)Pip ,
8872 octetsIdée tirée du CJam d' Optimizer . Mon coup initial au problème avec un analyseur de descente récursif était ... plutôt plus long.
Formaté, avec explication:
Astuces intéressantes:
0X,5
, par exemple, est0 X [0 1 2 3 4] == ["" "0" "00" "000" "0000"]
.R
opérateur ternaire eplace peut prendre une liste pour n'importe lequel de ses arguments:"abracadabra" R ["br" "ca"] 'b
donneababdaba
, par exemple. Je fais bon usage de cette fonctionnalitéz
ici.""
vide, la liste vide[]
et tout scalaire qui est zéro. Ainsi,0
est faux, mais aussi0.0
et"0000000"
. Cette fonctionnalité est parfois gênante (pour tester si une chaîne est vide, il faut tester sa longueur car elle"0"
est fausse aussi), mais pour ce problème c'est parfait.la source
Javascript (ES6),
289288285282278244241230 octetsla source