Dans le livre d'informatique populaire (et essentiel), Une introduction aux langages formels et aux automates de Peter Linz, le langage formel suivant est fréquemment mentionné:
principalement parce que ce langage ne peut pas être traité avec des automates à états finis. Cette expression signifie "La langue L consiste en toutes les chaînes de 'a suivies de' b's, dans lesquelles le nombre de 'a et de b est égal et non nul".
Défi
Ecrivez un programme / fonction de travail qui obtient une chaîne contenant uniquement "a" s et "b" s , puis renvoie / renvoie une valeur de vérité , en indiquant si cette chaîne est valide le langage formel L.
Votre programme ne peut utiliser aucun outil de calcul externe, y compris réseau, programmes externes, etc. Les shells sont une exception à cette règle; Bash, par exemple, peut utiliser des utilitaires de ligne de commande.
Votre programme doit renvoyer / afficher le résultat de manière "logique", par exemple: renvoyer 10 au lieu de 0, "bip", émettre vers stdout, etc. Pour plus d'informations, cliquez ici.
Les règles de golf standard sont appliquées.
Ceci est un code-golf . Le code le plus court en octets gagne. Bonne chance!
Cas de test de vérité
"ab"
"aabb"
"aaabbb"
"aaaabbbb"
"aaaaabbbbb"
"aaaaaabbbbbb"
Cas de tests de fausseté
""
"a"
"b"
"aa"
"ba"
"bb"
"aaa"
"aab"
"aba"
"abb"
"baa"
"bab"
"bba"
"bbb"
"aaaa"
"aaab"
"aaba"
"abaa"
"abab"
"abba"
"abbb"
"baaa"
"baab"
"baba"
"babb"
"bbaa"
"bbab"
"bbba"
"bbbb"
la source
empty string == truthy
etnon-empty string == falsy
serait acceptable?a^n b^n
ou similaire, plutôt que juste le nombre dea
s égal au nombre deb
s)Réponses:
MATL ,
54 octetsImprime un tableau non vide de 1 s si la chaîne appartient à L , et un tableau vide ou un tableau avec 0 s (les deux sont faussés) sinon.
Merci à @LuisMendo pour le golf d'un octet!
Essayez-le en ligne!
Comment ça fonctionne
la source
Python 3, 32 octets
Sorties via le code de sortie : erreur pour faux, pas d'erreur pour vrai.
La chaîne est évaluée en tant que code Python, remplaçant les parenthèses
(
poura
et)
pourb
. Seules les expressions de la formea^n b^n
deviennent des expressions bien formées de parenthèses telles que((()))
, évaluées au tuple()
.Toute parenthèse mal assortie donne une erreur, de même que plusieurs groupes
(()())
, comme il n'y a pas de séparateur. La chaîne vide échoue également (elle réussiraitexec
).La conversion
( -> a
,) -> b
est effectuée à l' aidestr.translate
, qui remplace les caractères comme indiqué par une chaîne qui sert de table de conversion. Étant donné la chaîne de 100 "" ("* 50), les tableaux mappent les 100 premières valeurs ASCII en tant quequi prend
( -> a
,) -> b
. Dans Python 2, les conversions pour toutes les 256 valeurs ASCII doivent être fournies, nécessitant"ab"*128
un octet de plus; merci à isaacg pour l'avoir signalé.la source
*128
fait?128
peut être remplacé par50
(ou99
d'ailleurs) pour sauvegarder un octet.Rétine , 12 octets
Crédits à FryAmTheEggman qui a trouvé cette solution de manière indépendante.
Imprime
1
pour une entrée valide et0
autre.Essayez-le en ligne! (La première ligne active une suite de tests séparée par saut de ligne.)
Explication
L'équilibrage des groupes nécessite une syntaxe coûteuse. J'essaie donc de réduire une entrée valide à un simple formulaire.
Étape 1
Le
+
dit à Retina de répéter cette étape dans une boucle jusqu'à ce que la sortie cesse de changer. Il correspond à ouab
ou lea;b
remplace par;
. Considérons quelques cas:a
s et lesb
s dans la chaîne ne sont pas équilibrés de la même manière que(
et)
doivent normalement être, certainsa
oub
resteront dans la chaîne, carba
, oub;a
ne peut pas être résolu et un seula
oub
sur son propre ne peut pas Soit. Pour se débarrasser de tous lesa
s etb
s, il doit en exister un qui correspondeb
à la droite de chacuna
.a
etb
ne sont pas tous imbriqués (par exemple si nous avons quelque chose commeabab
ouaabaabbb
), nous nous retrouverons avec plusieurs;
(et potentiellement quelquesa
s etb
s), car la première itération trouvera plusieursab
s pour les insérer et les autres itérations seront préservées. le nombre de;
dans la chaîne.Par conséquent, si et seulement si l'entrée est de la forme , nous en aurons un seul dans la chaîne.
anbn
;
Étape 2:
Vérifiez si la chaîne obtenue ne contient qu'un seul point-virgule. (Quand je dis "cocher" je veux dire en fait, "compte le nombre de correspondances de la regex donnée, mais puisque cette regex peut correspondre au maximum une fois en raison des ancres, cela donne l'un
0
ou l' autre1
.)la source
Haskell, 31 octets
La compréhension de la liste
[c|c<-"ab",'a'<-s]
fait une chaîne d'un'a'
pour chaque'a'
ens
, suivi d'un'b'
pour chaque'a'
ens
. Cela évite de compter en faisant correspondre une constante et en produisant une sortie pour chaque correspondance.Cette chaîne est vérifiée pour être égale à la chaîne d'origine et la chaîne d'origine est vérifiée pour être non-vide.
la source
f=g.span id.map(=='a');g(a,b)=or a&&b==(not<$>a)
). Bien joué.Grime , 12 octets
Essayez-le en ligne!
Explication
La première ligne définit un non terminal
A
, qui correspond à une lettrea
, éventuellement le non terminalA
, et ensuite à une lettreb
. La deuxième ligne correspond à l'entrée entière (e
) par rapport au terminalA
.Version non compétitive de 8 octets
Après avoir écrit la première version de cette réponse, j'ai mis à jour Grime afin qu'il prenne en compte
_
le nom de l'expression de niveau supérieur. Cette solution est équivalente à la précédente, mais évite de répéter l’étiquetteA
.la source
Brachylog ,
2319 octetsEssayez-le en ligne!
Explication
la source
05AB1E , 9 octets
Code:
Explication:
Les deux derniers octets peuvent être supprimés s'il est garanti que l'entrée est non vide.
Utilise le codage CP-1252 . Essayez-le en ligne! .
la source
.M{J¹ÔQ0r
pour le vôtre.Gelée , 6 octets
Imprime la chaîne elle-même si elle appartient à L ou est vide, et 0 sinon.
Essayez-le en ligne! ou vérifier tous les cas de test .
Comment ça fonctionne
Version alternative, 4 octets (non concurrente)
Imprime 1 ou 0 . Essayez-le en ligne! ou vérifier tous les cas de test .
Comment ça fonctionne
la source
J, 17 octets
Cela fonctionne correctement pour donner falsey à la chaîne vide. L'erreur est falsey.
Anciennes versions:
Preuve et explication
Le verbe principal est un fork composé de ces trois verbes:
Cela signifie "le moindre de (
<.
) la longueur (#
) et le résultat de la tine droite ((-:'ab'#~-:@#)
)".La dent droite est un train à 4 trains , composé de:
Laissons
k
représenter notre contribution. Ensuite, cela équivaut à:-:
est l'opérateur de correspondance, donc les principaux-:
tests d'invariance sous la fourche monadique'ab' #~ -:@#
.Puisque la dent gauche de la fourche est un verbe, elle devient une fonction constante. Donc, la fourchette équivaut à:
La dent droite de la fourche réduit de moitié (
-:
) la longueur (#
) dek
. Observez#
:Maintenant, cela
k
ne concerne que les entrées valides, nous avons donc terminé ici.#
des erreurs pour des chaînes de longueur impaire, qui ne satisfont jamais la langue, nous avons donc également terminé.Combinée avec le moindre de la longueur et celle-ci, la chaîne vide, qui ne fait pas partie de notre langage, donne sa longueur
0
, et nous en avons terminé avec tout.la source
2&#-:'ab'#~#
qui devrait vous permettre d'éviter l'erreur et de générer une sortie0
tout en utilisant 12 octets.Bison / YACC 60 (ou 29) octets
(Eh bien, la compilation d'un programme YACC se fait en deux étapes. Vous voudrez peut-être en inclure quelques-unes. Voir les détails ci-dessous.)
La fonction devrait être assez évidente si vous savez l’interpréter en termes de grammaire formelle. L'analyseur accepte soit
ab
una
suivi suivi de toute séquence acceptable suivi d'un pointb
.Cette implémentation repose sur un compilateur qui accepte la sémantique de K & R pour perdre quelques caractères.
C'est plus mot que je voudrais avec la nécessité de définir
yylex
et d'appelergetchar
.Compiler avec
(la plupart des options de gcc sont spécifiques à mon système et ne doivent pas être comptées dans le nombre d'octets; vous pouvez vouloir compter
-std=c89
ce qui ajoute 8 à la valeur indiquée).Courir avec
ou équivalent.
La valeur de vérité est renvoyée au système d'exploitation et les erreurs sont également signalées
syntax error
à la ligne de commande. Si je ne peux compter que la partie du code qui définit la fonction d'analyse (c'est-à-dire négliger la seconde%%
et tout ce qui suit), j'obtiens un compte de 29 octets.la source
Perl 5.10,
3517 octets (avec l' indicateur -n )Garantit que la chaîne commence par
a
s, puis se répète surb
s. Il ne correspond que si les deux longueurs sont égales.Merci à Martin Ender pour avoir réduit de moitié le nombre d'octets et m'avoir appris un peu plus sur la récursion dans les regexes: D
Il renvoie la chaîne entière si elle correspond, et rien sinon.
Essayez-le ici!
la source
$_&&=y/a//==y/b//
(nécessite-p
), sans le vide, vous pouvez déposer le&&
pour 16! Si proche ...echo -n 'aaabbb'|perl -pe '$_+=y/a//==y/b//'
mais je ne peux pas décaler un autre octet ... Il faudrait peut-être abandonner cela!JavaScript,
545544Construit un regex simple basé sur la longueur de la chaîne et le teste. Pour une longueur de 4 chaînes (
aabb
), l'expression régulière ressemble à ceci:^a{2}b{2}$
Renvoie une valeur de vérité ou de falsey.
11 octets sauvés grâce à Neil.
la source
f=
peut être omis.s=>s.match(`^a{${s.length/2}}b+$`)
?C,
5753 octetsAncienne solution longue de 57 octets:
Compilé avec gcc v. 4.8.2 @ Ubuntu
Merci Ugoren pour les conseils!
Essayez-le sur Ideone!
la source
(t+=2)
àt++++
-1 octet.t++++
n'est pas un code C valide.t+=*s%2*2
et:*s*!1[s]
Rétine , 22 octets
Une autre réponse plus courte dans la même langue est arrivée ...
Essayez-le en ligne!
Ceci est une vitrine des groupes d'équilibrage dans regex, ce qui est expliqué en détail par Martin Ender .
Comme mon explication ne serait pas proche de la moitié de celle-ci, je me contenterai de la relier et de ne pas tenter de l'expliquer, car cela nuirait à la gloire de son explication.
la source
Befunge-93, 67 octets
Essayez-le ici! Peut-être expliquer comment cela fonctionne plus tard. Peut-être aussi essayer de jouer au golf juste un peu plus, juste pour les coups de pied.
la source
MATL , 9 octets
Essayez-le en ligne!
Le tableau en sortie est véridique s'il est non vide et que toutes ses entrées sont non nulles. Sinon c'est de la fausseté. Voici quelques exemples .
la source
code machine x86,
29 à27 octetsHexdump:
Code d'assemblage:
Itère sur les
a
octets au début, puis sur les octets 'b' suivants. La première boucle augmente le compteur et la seconde le diminue. Ensuite, effectuez un OU au niveau du bit entre les conditions suivantes:b
s n'est pas 0, la chaîne ne correspond pas non plusEnsuite, il doit "inverser" la valeur de vérité en le
eax
mettant à 0 si ce n'est pas 0, et vice versa. Il s'avère que le code le plus court est le code à 5 octets suivant, que j'ai volé dans la sortie de mon compilateur C ++ pourresult = (result == 0)
:la source
neg eax
pour définir l’indicateur de retenue comme avant,cmc
pour inverser l’indicateur de retenue etsalc
réglez AL sur FFh ou 0 selon que l’indicateur de retenue est activé ou non. Enregistre 2 octets, bien que le résultat obtenu soit un résultat sur 8 bits plutôt que sur 32 bits.xor eax,eax | xor ecx,ecx | l1: inc ecx | lodsb | cmp al, 'a' | jz l1 | dec esi | l2: lodsb | cmp al,'b' | loopz l2 | or eax,ecx | setz al | ret
Ruby, 24 octets
(Ce n'est que la brillante idée de xnor sous la forme ruby. Mon autre réponse est une solution que je me suis proposée.)
Le programme prend l'entrée, se transforme
a
etb
à[
et]
respectivement, et l' évalue.Une entrée valide formera un tableau imbriqué et rien ne se passe. Une expression déséquilibrée fera planter le programme. En Ruby, l'entrée vide est évaluée en tant que
nil
, ce qui plantera carnil
aucune*
méthode n'a été définie .la source
Sed, 38 + 2 = 40 octets
Une sortie de chaîne non vide est vérité
Les automates finis ne peuvent pas faire cela, vous dites? Qu'en est-il des automates à états finis avec des boucles . : P
Courir avec
r
et desn
drapeaux.Explication
la source
JavaScript,
444244 barré est toujours régulier 44;
Fonctionne en supprimant récursivement l'extérieur
a
etb
et de manière récursive en utilisant la valeur interne sélectionnée, mais.+
. Lorsqu'il n'y a pas de correspondance à^a.+b$
gauche, le résultat final est de savoir si la chaîne restante est la valeur exacteab
.Cas de test:
la source
ANTLR, 31 octets
Utilise le même concept que la réponse YACC de @ dmckee , juste un peu plus joué.
Pour tester, suivez les étapes du didacticiel de prise en main d'ANTLR . Ensuite, placez le code ci-dessus dans un fichier nommé
A.g4
et exécutez les commandes suivantes:Puis testez en donnant une entrée sur STDIN pour
grun A r
aimer ainsi:Si l'entrée est valide, rien ne sera généré. si elle est invalide,
grun
donnera une erreur (soittoken recognition error
,extraneous input
,mismatched input
ouno viable alternative
).Exemple d'utilisation:
la source
grammer
mot-clé est un frein au golf avec antlr, cependant. Un peu comme utiliser fortran .C, 69 octets
69 octets:
#define f(s)strlen(s)==2*strcspn(s,"b")&strrchr(s,97)+1==strchr(s,98)
Pour les inconnus:
strlen
détermine la longueur de la chaînestrcspn
renvoie le premier index de la chaîne où l'autre chaîne est trouvéestrchr
renvoie un pointeur sur la première occurrence d'un caractèrestrrchr
renvoie un pointeur sur la dernière occurrence d'un caractèreUn grand merci à Titus!
la source
>97
au lieu de==98
R,
646155 octets,7367 octets (robuste) ou 46 octets (si les chaînes vides sont autorisées)Encore une fois, la réponse de xnor retravaillée. Si les règles impliquent que l'entrée se compose d'une chaîne de
a
s et deb
s, cela devrait fonctionner: renvoie NULL si l'expression est valide, renvoie et erreur ou rien sinon.Si l'entrée n'est pas robuste et peut contenir des erreurs, par exemple
aa3bb
, la version suivante doit être considérée (doit renvoyerTRUE
pour les vrais tests, pas NULL):Enfin, si les chaînes vides sont autorisées, nous pouvons ignorer la condition pour une entrée non vide:
Encore une fois, NULL en cas de succès, tout le reste.
la source
NULL
), la version 2: il suffit de rien (retourne entrée correcte uniquementTRUE
), la version 3 ( en supposant que les chaînes vides sont OK, comme état):NULL
. R est un langage statistique orienté objet qui permet de tout dactylographier correctement, sans aucun avertissement.if((y<-scan(,''))>'')eval(parse(t=chartr('ab','{}',y)))
Japt , 11 octets
Essayez-le en ligne!
Donne soit
true
oufalse
, sauf que""
donne""
qui est la fausseté dans JS.Déballé et comment ça marche
Adopté de la solution MATL de Dennis .
la source
C (Ansi),
65 à75 octetsGolfé:
Explication:
Définit une valeur j et incrémente j sur chaque b et décrémente j sur toute autre chose. Vérifié si la lettre précédente est inférieure ou égale à la lettre suivante afin d'éviter que l'abab ne fonctionne
Édite
Ajout de contrôles pour les cas d'abab.
la source
ba
ouabab
?Lot, 133 octets
Retourne un
ERRORLEVEL
0 en cas de succès, 1 en cas d'échec. Batch n'aime pas faire de remplacement de sous-chaîne sur des chaînes vides, nous devons donc vérifier cela d'avance; si un paramètre vide était légal, la ligne 6 ne serait pas nécessaire.la source
PowerShell v2 +,
6152 octetsPrend l'entrée
$n
sous forme de chaîne, crée en$x
tant quehalf the length
. Constructions une-and
comparaison booléenne entre$n
un-match
opérateur de regex et le regex d'un nombre égal dea
'et deb
'. Sorties Booléenne$TRUE
ou$FALSE
. Le$n-and
est là pour rendre compte de""
=$FALSE
.Alternatif, 35 octets
Ceci utilise la regex de la réponse de Leaky , basée sur des groupes d'équilibrage .NET, juste encapsulés dans l'
-match
opérateur PowerShell . Renvoie la chaîne pour vérité ou la chaîne vide pour falsey.la source
-match
contre$args[0]
, sinon-match
fonctionnera comme un filtre[0]
ici parce que nous ne recevons qu'une entrée et que nous n'avons besoin que d'une valeur de vérité / falsey en sortie. Puisqu'une chaîne vide est falsey et qu'une chaîne non vide est une vérité, nous pouvons filtrer le tableau et récupérer la chaîne d'entrée ou rien, ce qui satisfait aux exigences du défi.Pyth - 13 octets
A expliqué:
la source
&qS*/lQ2"ab
+4
s'étendra à+4Q
(remplissage implicite d'arguments)Haskell, 39 octets
Exemple d'utilisation:
p "aabb"
->True
.scanl(\s _->'a':s++"b")"ab"x
construire une liste de tous["ab", "aabb", "aaabbb", ...]
avec un total d'(length x)
éléments.elem
vérifie six
est dans cette liste.la source
Python,
43 à40 octetsa identifié la solution évidente grâce à Leaky Nun
autre idée, 45 octets:
-4 octets en utilisant len / 2 (j'obtiens une erreur quand la moitié arrive en dernier)
donne maintenant faux pour la chaîne vide
-3 octets grâce à xnor
la source
lambda s:list(s)==sorted("ab"*len(s)//2)
(Python 3)lambda s:s=="a"*len(s)//2+"b"*len(s)//2
(Python 3)''<
au lieu d's and
éliminer le cas vide.