Encore un autre problème d'analyse de Brainfuck, mais cette fois ... différent.
Vous travaillez dans Infinite Monkeys Incorporated, la société qui fabrique des programmes Brainfuck, pour résoudre divers problèmes intéressants (par accident, pas moins - après tout, la société crée des programmes aléatoires). Cependant, il semble que vos machines Turing rapides qui n'exécutent que Brainfuck ont un petit problème coûteux d'erreurs de syntaxe - faites-en un, et l'ordinateur explose. C'est probablement un défaut de conception, mais personne n'avait pris la peine de comprendre pourquoi cela se produisait.
Comme les machines Turing (en particulier les machines rapides) sont chères (après tout, elles ont une RAM infinie qui coûte), il serait préférable de s'assurer que le programme n'a pas d'erreurs de syntaxe avant d'exécuter le code. Votre entreprise va exécuter beaucoup de code, donc la vérification manuelle ne fonctionnera pas. Écrivez un programme qui lit le code STDIN for Brainfuck et se termine avec un état de sortie défini sur autre chose que 0 (erreur) si le programme a une erreur de syntaxe (par exemple,
]
est une erreur de syntaxe, car il n'y a pas de correspondance[
). Quittez avec le statut de sortie réglé sur 0 si le programme est tout à fait correct.Assurez-vous que votre programme remarque correctement les erreurs impliquant
[]
. Vous ne voudriez pas qu'un autre ordinateur explose, n'est-ce pas? Oh, et assurez-vous que c'est aussi court que possible - votre patron paie pour des programmes courts (parce qu'il pense qu'ils sont rapides, ou quelque chose). Oh, et vous n'avez pas à coder dans Brainfuck (en fait, vous ne pouvez pas, car Brainfuck ne prend pas en charge les codes de sortie) - votre code sera exécuté sur un ordinateur normal.
Donc, comme vous pouvez le voir, votre travail consiste à vérifier si le programme Brainfuck est "valide" (a des []
symboles associés ). Veuillez noter que les programmes Brainfuck peuvent avoir d'autres caractères que []
, alors ne refusez pas le programme simplement parce qu'il a d'autres commandes. Le plus petit code gagne, mais vous vous soucierez probablement plus des votes positifs de toute façon.
la source
GCD(a,b)
place de0 != a || b
.Réponses:
GolfScript, 18 caractères
Ce code s'exécute correctement avec le code de sortie 0 (et imprime des ordures sur stdout) si les crochets dans l'entrée sont équilibrés. Si ce n'est pas le cas, il échoue avec un code de sortie différent de zéro et affiche un message d'erreur sur stderr, par exemple:
ou
Étant donné que le défi n'a rien dit sur la sortie vers stdout / stderr, je pense que cela est admissible. Dans tous les cas, vous pouvez toujours les rediriger vers
/dev/null
.Explication:
Le code
{[]`?)},
supprime tout sauf les crochets de l'entrée et~
évalue le résultat en tant que code GolfScript. La partie délicate est que les crochets non équilibrés sont parfaitement légaux dans GolfScript (et, en effet, mon code en inclut un!), Nous avons donc besoin d'une autre façon de faire planter le code.L'astuce que j'utilise est de laisser une copie de l'entrée au bas de la pile, de collecter la pile entière dans un tableau (en utilisant le déséquilibré
]
) et de décaler le premier élément. À ce stade, trois choses peuvent se produire:[
, essayer de décaler un élément d'un tableau vide plantera l'interpréteur (ce qui, dans ce cas, est exactement ce que nous voulons!)]
ou un non fermé[
), ce sera un tableau.Mon entrée originale de 14 caractères a ensuite comparé la valeur décalée avec une chaîne, ce qui se bloquerait s'il s'agissait d'un tableau imbriqué. Malheureusement, il s'avère que la comparaison d'un tableau plat (ou, en particulier, vide) avec une chaîne est également légale dans GolfScript, j'ai donc dû changer de tactique.
Ma soumission actuelle, à la place, utilise une méthode très brute pour différencier les tableaux des chaînes: elle les dévalue et essaie de trouver la première occurrence de
[
(code ASCII 91), qui sera nulle si et seulement si la valeur n'est pas évaluée. variable était un tableau. Si c'est le cas, la division du zéro avec lui-même déclenche le crash souhaité.Ps. Deux autres solutions de 18 caractères sont:
et
Hélas, je n'ai pas encore trouvé de moyen plus court pour résoudre le "problème de tableau vide".
la source
][
(c.-à-d. échoue-t-il dans votre programme?)[[]
; Je l'ai corrigé maintenant, au prix de 4 caractères, et il passe tous mes tests maintenant.1+
transformera un tableau vide en tableau non vide, un tableau non vide en tableau non vide et une chaîne en chaîne..{[]`?)},~](n<
. J'ai essayé votre1+
, mais il semble que le tableau doit contenir autre chose qu'un nombre (probablement pour que l'interpréteur se bloque lorsqu'il essaie de comparer récursivement un caractère avec un tableau / une chaîne). L'utilisationn+
ne fonctionne pas non plus, car elle contraint le tableau à une chaîne;[n]+
fait le travail, mais me met encore à 18 caractères.Brainfuck 76 octets
Cela sort de ses liens si les crochets ne sont pas équilibrés, ce qui fait que l'interpréteur / compilateur bf échoue à l'exécution et que certains d'entre eux ont des codes de sortie pour refléter cela.
nécessite eof = 0, des valeurs d'encapsulation et un nombre fini de cellules
Dans Ubuntu, vous pouvez utiliser l'interpréteur
bf
(sudo apt-get install bf
)la source
Brainfuck
Turing est complet sans E / S car vous pouvez exécuter un programme qui calcule n'importe quel calcul et voir le résultat en inspectant sa mémoire après l'exécution. BF sans E / S rendrait les gens moins intéressés car il serait difficile de créer des utilitaires. par exemple, je n'aurais jamais pu faire mon interprète lisp .Befunge 98 -
26312019 caractèresJe me suis débarrassé de certains conditionnels massifs. Maintenant, le programme fonctionne comme suit:
q
quitte le programme et affiche la valeur supérieure comme valeur d'erreur. La valeur d'erreur sera-11 s'il y en a trop]
, 0 si elles sont équilibrées etpositivenégative s'il y en a trop[
. Si le nombre estpositifnégatif, alorsautant devaleurs absolues de ce nombre]
sont nécessaires pour équilibrer le programme.Modifier: incrémentation et décrémentation commutées.
[
utilisé pour incrémenter le compteur et]
utilisé pour le décrémenter. En le commutant, j'enregistre 1 caractère, car pour la condition de sortie, je n'ai qu'à vérifier si le compteur est positif plutôt que négatif.Ancienne version
Ce code fonctionne comme suit:
Edit: réalisé que ces entrées acceptées comme
][
, maintenant, il se termine chaque fois que le compte devient négatif, en utilisantla source
[
et]
pour faire la comparaison avec les deux.J (
3835)Explication:
1!:1[3
: lire stdin'[]'=/
: créer une matrice où la première ligne est un masque de bits du[
s en entrée, et la deuxième ligne est le]
s.1 _1*
: multipliez la première ligne par 1 et la deuxième ligne par -1.+/
: additionner les colonnes de la matrice, donnant une delta-indentation par caractère+/\
: créer un total cumulé de ces derniers, donnant un niveau d'indentation à chaque personnage({:+.<./)
: retourne le GCD de l'élément final ({:
) et du plus petit élément (<./
). Si tous les accolades correspondent, les deux devraient être0
ainsi cela reviendra0
. Si les accolades ne correspondent pas, il renverra une valeur différente de zéro.exit
: définissez la valeur de sortie sur celle-ci et quittez.la source
rubis (64)
auparavant (68), c'était:
Une autre solution équivalente utilise
ne peut pas être utilisé
size
seul car cela donnerait de faux négatifs (!!!) lorsque le nombre total de parenthèses non équilibrées est multiple de 256la source
=
opérateur.0
peuvent aller.Perl, 30 caractères
Votre regex récursif de base Perl à la rescousse:
Pour ceux qui ne connaissent pas les arguments de ligne de commande utilisés ici:
-0
permet de définir le caractère de fin de ligne à des fins d'entrée de fichier; l'utilisation-0
sans argument définit le caractère de fin de ligne sur EOF.-n
lit automatiquement l'entrée (dans ce cas, le fichier entier) au$_
préalable.Si l'expression régulière correspond, elle renvoie une valeur vraie, qui est annulée à 0 pour le code de sortie. Sinon, la fausse valeur de retour donne un code de sortie de 1.
la source
bash (tr + sed) - 42
Si cela ne vous dérange pas, vous pouvez supprimer le dernier espace entre
`
et]
pour obtenir la longueur 41.la source
cat
et$()
("[]"
peut également être écrit comme[]
). J'ai accepté cette réponse, mais jusqu'à ce que je vois des améliorations de longueur, je ne vais pas voter contre cela, car même s'il est court, il pourrait être beaucoup plus court pour bash.$()
par des backticks et j'ai fait le"[]"
->[]
vous avez suggéré.Perl (56 caractères)
La solution Perl évidente: une expression régulière récursive. Malheureusement, c'est une construction assez verbeuse.
la source
Haskell (143)
à jgon: L'utilisation de 2 gardes semble être plus dense que si-alors-sinon. De plus, je ne pense pas que le vôtre vérifie que les crochets sont dans le bon ordre ("] [" passe)
la source
C,
7364 caractèresMerci aux suggestions de la boîte à pain (bien que cela nécessite probablement du petit endian pour fonctionner):
Comment ça fonctionne:
i
est initialisé à 0c
devient un int implicite qui obtientargc
(initialisé à 1 mais on s'en fiche, tant que les bits supérieurs ne sont pas définis)read(0,&c,1)
lit un seul caractère dans l'octet de poids faible de c (sur les architectures little-endian) et retourne 0 à EOF;i+1 != 0
sauf si la citation entre crochets équilibrés passe à -1; les multiplier ensemble fonctionne comme un booléen (sûr) ET qui prend un caractère de moins que&&
c==91
est évalué à 1 pour'['
, etc==93
évalue à 1 pour']'
. (Il pourrait y avoir une astuce de bricolage qui serait plus petite mais je ne pense à rien.)return i
quitte avec le code d'état 0 s'il est équilibré, différent de zéro s'il ne l'est pas. Renvoyer -1 viole techniquement POSIX mais personne ne s'en soucie vraiment.La version précédente:
la source
getchar()
au lieu de lire raccourcira le code et vous permettra d'utiliser (implicite)int
au lieu dechar
pour votre variable. N'oubliez pas non plus que les globaux sont automatiquement initialisés à zéro.c;
définit un entier global.][
? Je suis sûr que ce n'est pas équilibré. N'avez-vous pas besoin de savoir s'il devient négatif au moins une fois?Lua, 56
la source
"^%b[]$"
Qu'est-ce que c'est? Peux-tu expliquer? Ce n'est sûrement pas une expression régulière?^
), à un ensemble équilibré de[
et]
avec tout ce qui se trouve entre (%b[]
) et à la fin de string ($
).GTB , 55
Misses
[]
Utilisez
0
pour arrêter.la source
MATHEMATICA, 88 caractères
la source
s name like
RegularExpression` etStringLength
je ne pourrai jamais gagner un contexte de golf en code texte avec Mathematica! :)ToCharacterCode
est beaucoup plus long que çaord
aussi ... PS: Qu'en est-il de la définition d'un code de sortie?Length[StringCases[s,"["|"]"]//.{x___,"[","]",y___}:>{x,y}]
Rubis,
5958Recherche l'ouverture et la fermeture du support, en comptant
[
comme 1 et]
comme -1, et quitte si le nombre tombe en dessous de 0.la source
exit 1
au cas où vous le demandez).Hassium , 104 octets
Complet (la note ne fonctionne pas dans l'interpréteur en ligne car input () est désactivé) ici
la source
Code de la machine de Turing,
286276 octetsEncore une fois, j'utilise la syntaxe de table de règles définie ici.
Termine en état
halt
pour accepter l'entrée et lahalt-err
rejeter.la source
halt-err
peut être plus court, commehalt*
par exemple.Pyth, 25 octets
Essayez-le en ligne!
Traduction Python 3:la source
Haskell (
167, 159)Je l'ai fait surtout pour le plaisir, si quelqu'un a des suggestions pour le raccourcir, je serais heureux de les entendre :)
Éditer: correction d'un problème signalé dans les commentaires (ajout de 11 octets).
Edit 2: Création d'une fonction auxiliaire pour tester les prédicats à l'aide de gardes inspirés par user13350, supprimant 8 octets.
la source
][
( souligné par user13350 )Stax ,
1411 caractèresExécuter et déboguer
Crédit à @recursive pour -3 octets.
Équivalent ASCII:
Supprimez tous les caractères sauf
[]
, puis supprimez[]
jusqu'à ce que la chaîne ne change plus. Retourne1
si la chaîne finale est vide.la source
.[]|&
pour filtrer les caractères, puis réutiliser le littéral pour 11