Préambule
Les entiers sont toujours pairs ou impairs . Les entiers pairs sont divisibles par deux, les entiers impairs ne le sont pas.
Lorsque vous ajoutez deux nombres entiers, vous pouvez en déduire si le résultat sera pair ou impair en fonction de la nature des sommands:
- Même + Même = Même
- Even + Odd = Odd
- Impair + Pair = Impair
- Odd + Odd = Pair
De même, lorsque vous multipliez deux nombres entiers, vous pouvez en déduire si le résultat sera pair ou impair en fonction du fait que les facteurs sont pairs ou impairs:
- Même * Même = Même
- Even * Odd = Even
- Odd * Even = Even
- Impair * Impair = Impair
Ainsi, si vous connaissez l'uniformité ou l'étrangeté de toutes les variables d'une expression mathématique impliquant uniquement l'addition et la multiplication, vous pouvez en déduire si le résultat sera pair ou impair.
Par exemple, nous pouvons affirmer avec certitude que cela (68 + 99) * 37
donne un impair, car un pair plus un impair ( 68 + 99
) est un impair, et que, parfois, un autre impair ( odd * 37
) donne un étrange.
Défi
Ecrivez un programme ou une fonction qui accepte une chaîne contenant uniquement les quatre caractères eo+*
. Cette chaîne représente une expression mathématique donnée sous forme de préfixe impliquant uniquement add ( +
) et multiplication ( *
). Chacun e
représente un nombre pair arbitraire et chacun o
un nombre impair arbitraire.
Votre tâche consiste à simplifier l'expression, à en imprimer ou à en renvoyer une seule, e
ou o
à déterminer si le résultat de l'expression est pair ou impair.
Vous pouvez supposer que l'entrée sera toujours en notation de préfixe valide. Plus précisément, chaque +
et *
aura toujours deux opérandes correspondants qui se produisent après. Ces opérandes peuvent être un seul e
ou o
, ou un autre +
ou une *
expression qui à son tour possède des opérandes.
Par exemple, l’entrée *+eoo
pourrait être lue comme mul(add(e, o), o)
, ou (e + o) * o
en notation infixe normale . Le e
et le premier o
sont les opérandes correspondant au +
, et +eo
et le dernier o
sont les opérandes correspondant au *
.
Pour que tout soit clair, voici quelques entrées non valides qui ont une notation de préfixe incorrecte:
eo
ooe
o+e
ee*
+*oe
+e*o
Une nouvelle ligne de fin dans la sortie convient, mais dans le cas contraire, un simple e
pour pair ou o
impair est tout ce qui doit être affiché.
Le code le plus court en octets gagne.
Cas de test
(Les lignes vides servent uniquement à séparer visuellement des cas similaires.)
e -> e
o -> o
+ee -> e
+eo -> o
+oe -> o
+oo -> e
*ee -> e
*eo -> e
*oe -> e
*oo -> o
+e+ee -> e
+e+eo -> o
+e+oe -> o
+e+oo -> e
+e*ee -> e
+e*eo -> e
+e*oe -> e
+e*oo -> o
+o+ee -> o
+o+eo -> e
+o+oe -> e
+o+oo -> o
+o*ee -> o
+o*eo -> o
+o*oe -> o
+o*oo -> e
*e+ee -> e
*e+eo -> e
*e+oe -> e
*e+oo -> e
*e*ee -> e
*e*eo -> e
*e*oe -> e
*e*oo -> e
*o+ee -> e
*o+eo -> o
*o+oe -> o
*o+oo -> e
*o*ee -> e
*o*eo -> e
*o*oe -> e
*o*oo -> o
++eee -> e
++eeo -> o
++eoe -> o
++eoo -> e
++oee -> o
++oeo -> e
++ooe -> e
++ooo -> o
+*eee -> e
+*eeo -> o
+*eoe -> e
+*eoo -> o
+*oee -> e
+*oeo -> o
+*ooe -> o
+*ooo -> e
*+eee -> e
*+eeo -> e
*+eoe -> e
*+eoo -> o
*+oee -> e
*+oeo -> o
*+ooe -> e
*+ooo -> e
**eee -> e
**eeo -> e
**eoe -> e
**eoo -> e
**oee -> e
**oeo -> e
**ooe -> e
**ooo -> o
+e+e+e+ee -> e
+o+o+o+oo -> o
*e*e*e*ee -> e
*o*o*o*oo -> o
+e+o+e+oe -> e
+o+e+o+eo -> o
*e*o*e*oe -> e
*o*e*o*eo -> e
+e*e+e*ee -> e
+o*o+o*oo -> o
*e+e*e+ee -> e
*o+o*o+oo -> o
+**++*+*eeoeeooee -> e
+**++*+***eooeoeooeoe -> e
+**+***+**++**+eooeoeeoeeoeooeo -> o
+e*o*e**eoe -> e
+*e+e+o+e**eeoe -> e
**o++*ee*++eoe*eo+eoo -> o
la source
eval
OK?Réponses:
CJam,
181713 octetsMerci à aditsu pour la sauvegarde de 4 octets.
Essayez la suite de tests ici. (La suite de tests est trop longue pour le permalien. Copiez-les simplement de la spécification du challenge.)
Explication
la source
Pyth,
16 à14 octetsPyth peut lui-même évaluer une chaîne, c'est-à-dire en syntaxe Pyth. Par conséquent je remplace
e
eto
avec4
et5
. Ensuite, l'évaluation me donnera un nombre pair ou impair, et je peux facilement imprimer le résultat.Essayez-le en ligne: démonstration ou suite de tests
Explication:
Explication supplémentaire à la remplacer.
G
est une variable initialisée avec l'alphabetabc...xyz
.U9
est la liste[0, 1, ..., 8]
.XzGU9
remplace les lettres de l'alphabet par les valeurs de la liste. Donc,a
est remplacé par0
,b
avec1
, ...,e
avec4
, ...,i
avec8
,j
avec0
, ..., eto
avec5
. Par conséquent, je suise
remplacé par un nombre pair eto
par un nombre impair. Tous les autres remplacements n'ont aucun effet.la source
Perl,
504540 caractères(Code de 39 caractères + Option de ligne de commande à 1 caractère.)
Échantillon échantillon:
la source
while/../
voussed
version… Merci, @primo.1while s/\+oe...
. Je suis aussi assez sûr que[+*]
peut être remplacé par\W
.gema
meRétine , 29 octets
Pour la version pratique à un fichier, l'
-s
indicateur est utilisé.Nous échangeons des expressions bizarres (
*oo
,+oe
,+eo
) ào
jusqu'à ce que nous pouvons, puis échanger les autres expressions symbole lettre lettre àe
. Nous le répétons jusqu'à ce que nous le puissions et la dernière lettre est notre résultat.(Cette solution est similaire à la réponse Perl de manatwork .)
Essayez-le en ligne! (par Dennis)
la source
Python 2, 90
La
iter
fonction est un bon moyen de transformer la chaîne d'entrée en une file d'attente FIFO qui se souvient de la quantité de chaîne analysée lors des appels def
. Comme il est idempotent, il est inoffensif de le rappeler lorsque l'entrée est déjà un itérateur plutôt qu'une chaîne. La dernière moitié de la réponse commençant paror'oe'
... semble devoir être jouable au golf, mais je n'ai rien trouvé.-1 grâce à Sp3000.
la source
iter
vraiment ahurissent mon esprit.eval
:def f(s,e=0,o=1):i=iter(s);a=next(i);return'eo'[eval(a*(a>'a')or f(i)+a+f(i))%2]
Mathematica,
9184 octetsVous cherchez un moyen de compresser cela ...
la source
//.
est plus court queFixedPoint
.Python 2, 80 octets
Ceci est construit sur la réponse très intelligente de feersum qui utilise un
iter
pour implémenter des opérations de notation en polonais. La nouvelle idée est d'utilisereval
pour évaluer les expressions+
et*
aveceval(f(i)+a+f(i))
, où l'opérateura
est placé infixe entre les résultats récursifs. Eval utilise les liaisonse=0,o=1
dans les arguments de la fonction optionnelle. La sortie est alors prise mod 2.la source
e+o
, il a donc besoin des variables pour faire référence à des nombres.C, 79 octets
Récursion directe. S'appuie sur certaines propriétés (coïncidentes?) Au niveau des bits des quatre caractères autorisés.
la source
Utilitaires Shell + GNU, 33
L'entrée provient de STDIN.
Il en va de même pour inverser l’entrée et l’évaluer avec une calculatrice basée sur la pile - dans ce cas
dc
. Nous pourrions remplacere
eto
par0
et1
, mais il faudrait alors insérer des espaces pour éviter une analyse gourmande des chiffres en chiffres incorrects.Au lieu de cela
e
est remplacé parK
qui est ladc
commande pour pousser la précision actuelle à la pile, qui par défaut est 0. Eto
est remplacé parO
qui est ladc
commande pour pousser la base de sortie actuelle à la pile. Cela doit être étrange, donc nous avons mis 15 avecFo
avant de faire quoi que ce soit en dc.Ensuite, il suffit de prendre le mod 2 et de l’imprimer
2%p
. Les seules valeurs possibles sont maintenant0
et1
, donc, que la base de sortie soit 15. Peu importe, puis esttr
traduit eno
oue
.J'aime que si vous plissiez les yeux, cette source ressemble presque
dc Forever OK
.la source
Sérieusement , 24 octets
Une manipulation plus efficace de la pile pourrait probablement rendre cela plus court, mais bon, ça me convient.
Prend les entrées sous forme de chaîne, comme
"+*oee"
Essayez-le en ligne (l'entrée doit être entrée manuellement)
Explication:
la source
Ruby, 61 octets
Utilisation de l'analyse récursive de descente et de l'algèbre de Boolean.
La fonction lit un caractère de stdin à la fois. S'il lit un
+
ou un*
, il s'appelle deux fois pour déterminer impair ou pair. La fonction retournetrue
pour impair etfalse
poureven
. Les opérateurs^
XOR et&
AND sont utilisés pour déterminer la "bizarrerie" des expressions d'addition et de multiplication, respectivement.Voici une version non-golfée:
Merci à @Shel d'avoir signalé un bogue dans la version initiale.
la source
+ee
donneo
. J'aime l'idéef^f
avec!f^f
etf&f
avecf|f
et cela fonctionne. Programme permettant d'exécuter desf^f
etf&f
et retourné$_==?e
et à la?e:?o
place :)Minkolang 0,14 , 40 octets
J'ai essayé de faire une méthode eval intelligente, mais il s'avère que les valeurs ajoutées à la boîte de code en dehors de l'espace d'origine ne seront jamais atteintes par le compteur de programme. J'ai donc fait une méthode d'évaluation moins intelligente. : P
Essayez ici.
Explication
la source
JavaScript,
110 10694 octetsCertainement pas la plus petite solution, mais probablement la plus petite solution possible dans un langage aussi prolixe que JavaScript!
la source
?:
.while(i.length>2)i=i.replace(/[+*][eo]{2}/,function(o){return"+oe+eo*oo".indexOf(o)>=0?"o":"e"})
. Ou si vous passez à la fonction de flèche épaisse d’ECMAScript 6, alorswhile(i.length>2)i=i.replace(/[+*][eo]{2}/,o=>"+oe+eo*oo".indexOf(o)>=0?"o":"e")
. Mais malheureusement, l'exigence dit programme ou fonction, alors que votre code actuel est un extrait. Il doit gérer soit les entrées et les sorties, soit les arguments et les valeurs renvoyées.i
comme vous l'avez dit.O ,
24201918 octetsPrend l'entrée, l'inverse, attribue
e
à 2 eto
à 1 et l'envoie à Tumblr, l'évalue en tant que code O.Explication:
la source
GNU Sed, 36
Après avoir affiché ce que j'ai vu exactement la même approche que la réponse Perl @ manatwork et la réponse Retina @ randomra . Donc, je suppose que je peux aussi bien aller jusqu'au bout et emprunter leurs
\W\w\w
aussi.Merci à @Ruud pour avoir rasé 4 octets.
la source
+
, vous perdez 2 octets pour vous échapper|
, mais le résultat final est que vous gagnez 1 octet pour l'option de largage-r
.|
qu'il fallait échapper à la situation quand il-r
n'était pas utilisé. Encore 2 octets de plus sur le score - merci!Haskell, 160 octets
Appel
f
.la source
JavaScript,
9271 octetsC'est un peu obscurci, mais je voulais faire quelque chose en utilisant
eval
des opérateurs au niveau des bits. Annoté:La répétition de
(e[…]>"e")
m'énerve un peu, mais ce qui suit n'est pas mieux non plus (103 octets):En fin de compte, l'approche de @ Arkain avec une simple correspondance de sous-chaîne est supérieure. Fait en une fonction, avec quelques optimisations:
la source
Dart, 173 octets
Ce n'est pas compétitif, mais peu importe. L’essentiel de la solution est, à partir de 0, de remplacer récursivement chaque opérateur par l’évaluation de la paire de caractères suivant cet opérateur, puis de supprimer ces caractères de la liste.
la source
Haskell, 231 octets
Voici une approche utilisant un langage sérieux;)
Version golfée:
Exemple:
Ungolfed et jolie version complète:
Exemple:
Caractéristiques: Correspondance des motifs et récursivité.
la source
Jolf, 11 octets
(Non compétitif, comme le langage postdate la question.) Essayez-le ici!
(Remplacez
\x12
par le caractère réel\x12
. Cela devrait être fait automatiquement dans l'interpréteur.)Explication:
la source
Python 3,
171145135 octetsPas compétitif, mais je me suis amusé à le faire, alors je ne pouvais tout simplement pas le garder pour moi. À la différence de l' entrée (très intelligente) récursive-itérateur de Python par feersum , celle-ci inverse l'entrée et effectue ensuite une bonne vieille analyse basée sur la pile de la notation polonaise inversée.
la source
callable()
élégant, mais long. (Inverser la condition et supprimernot
seraient plus courts.) Vérifiez plutôt si m est un entierm in[0,1]
, mais vérifier si c est une valeurc in'eo'
serait encore plus court. Ce dernier étant le même quec>'a'
dans ce cas.for
:s+=[c>'e'if c>'a'else{'*':o.and_,'+':o.xor}[c](s.pop(),s.pop())]
s.pop()
(deux fois) chaque boucle. Je n'ai pas pris la peine de tester jusqu'à maintenant; mais bon, le point est discutable maintenant.operator
module?bool.__and__()
etbool.__xor__()
sont plus maniables:s+=[c>'e'if c>'a'else getattr(s.pop(),{'*':'__and__','+':'__xor__'}[c])(s.pop())]
. Mais en se basant sur la pointe de tranchage de gnibbler , il est possible de changer cela en .s+=[c>'e'if c>'a'else getattr(s.pop(),'__'+('axnodr'[c>'*'::2])+'__')(s.pop())]
^
,&
) et leursoperator
homologues, en oubliant les méthodes qui les implémentent réellement. Oh, etreversed()
a maintenant été abandonné grâce à un autre des conseils de golf Python .Haskell,
9894 octetsDésolé de vous déranger avec encore une autre tentative de Haskell; je voulais juste prouver que c'est très bien possible en moins de 100 octets.
Définit une fonction
p
qui accepte toute expression valide en tant que paramètre et renvoie le résultat sous la forme d'une chaîne de longueur 1.Exemple:
La fonction fonctionne en réduisant de manière répétée l'opérateur le plus à droite de la chaîne jusqu'à ce qu'il ne reste plus aucun opérateur.
la source
Ajouter ++ , 46 octets
Essayez-le en ligne!
Le pied de page énumère simplement tous les exemples d'entrées et leurs sorties correspondantes.
Comment ça fonctionne
Comme une perte de réponses ici, cela utilise remplacement et évaluation. Notre fonction principale est
f
etg
est une fonction d'assistance. Nous allons utiliser"*e*o*e*oe"
(ce qui este
) à titre d'exemple.f
commence par prendre la chaîne d'entrée et l'inverser, en cédant"eo*e*o*e*"
. Nous cartographionsg
ensuite chaque élément:g
commence par dupliquer l'argument, pour conserver une copie jusqu'à la commande finale. Nous vérifions ensuite si l'argument est dans la chaîne"oe"
, donnant 1 pour les lettres et 0 pour*
ou+
. Nous repoussons ensuite l'argument et vérifions s'il est égal à"e"
. Ce résultat est ensuite ajouté au contrôle précédent. Cela donne 0 pour*
ou+
, 1 pouro
et 2 poure
. Nous prenons alors le OU logique entre cette valeur et l'argument. Si la valeur est 0 , il est remplacé par l'argument (c'est-à*
- dire ou+
), sinon il est laissé tel quel (c'est-à-dire 1 et 2 ).Ceci convertit toutes les lettres à l’inverse de l’entrée en une valeur numérique. Nous joignons ensuite chaque élément par des espaces pour nous assurer que les chiffres ne sont pas concaténés. Pour notre exemple, cela donne la chaîne
"2 1 * 2 * 1 * 2 *"
. Nous pouvons ensuite évaluer cela en utilisant la notation postfixée de Add ++, ce qui donne 8 . Nous prenons ensuite la parité de cette valeur, en donnant soit 0 pour les nombres pairs et 1 pour les nombres impairs, avant l'indexation dans la chaîne"eo"
et le renvoi de la lettre correspondante.la source