Eh bien c'est étrange… non attendez, c'est même!

70

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) * 37donne 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 ereprésente un nombre pair arbitraire et chacun oun nombre impair arbitraire.

Votre tâche consiste à simplifier l'expression, à en imprimer ou à en renvoyer une seule, eou 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 eou o, ou un autre +ou une *expression qui à son tour possède des opérandes.

Par exemple, l’entrée *+eoopourrait être lue comme mul(add(e, o), o), ou (e + o) * oen notation infixe normale . Le eet le premier osont les opérandes correspondant au +, et +eoet le dernier osont 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 epour pair ou oimpair 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
Les passe-temps de Calvin
la source
8
Pouvons-nous prendre 1 et 0 au lieu de e et o en entrée?
ghosts_in_the_code
8
@ghosts_in_the_code Non, désolé.
Calvin's Hobbies
2
Est-ce que j'utilise evalOK?
xnor
1
@xnor Bien sûr. Tout ce qui fonctionne.
Calvin's Hobbies
2
Je doute que je puisse utiliser cela pour battre les 13 octets déjà publiés, mais je remarque que l’addition correspond à un ou exclusif et une multiplication à un simple ou.
WGroleau

Réponses:

43

CJam, 18 17 13 octets

Merci à aditsu pour la sauvegarde de 4 octets.

qW:O%eu~"eo"=

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

q     e# Read the input.
W:O   e# Push a -1 and store it in variable O.
%     e# Use the -1 to reverse the string, because CJam's stack-based nature and the
      e# commutativity of the operators means we can evaluate the code in postfix notation.
eu    e# Convert the string to upper case, turning 'e' into 'E' (a variable with even value
      e# 14) and 'o' into 'O' (which we've stored the odd value -1 in).
~     e# Evaluate the string as CJam code, leaving the result on the stack.
"eo"= e# Use the result as an index into the string "eo". CJam's indexing is cyclic so it
      e# automatically takes inputs modulo 2. Negative indices also work as expected.
Martin Ender
la source
27

Pyth, 16 à 14 octets

@"eo".vjdXzGU9

Pyth peut lui-même évaluer une chaîne, c'est-à-dire en syntaxe Pyth. Par conséquent je remplace eet oavec 4et 5. 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:

@"eo".vjdXzGU9   implicit: z = input string
         XzGU9   replace "e" in z with 4 and "o" with 5
       jd        put a space between each char
     .v          evaluate it (Pyth style)
@"eo"            and print "e" or "o"

Explication supplémentaire à la remplacer. Gest une variable initialisée avec l'alphabet abc...xyz. U9est la liste [0, 1, ..., 8]. XzGU9remplace les lettres de l'alphabet par les valeurs de la liste. Donc, aest remplacé par 0, bavec 1, ..., eavec 4, ..., iavec 8, javec 0, ..., et oavec 5. Par conséquent, je suis eremplacé par un nombre pair et opar un nombre impair. Tous les autres remplacements n'ont aucun effet.

Jakube
la source
Pourquoi inversez-vous l'expression? Aussi, n'avez-vous pas besoin de prendre le résultat modulo 2, ou est-ce que l'indexation est enveloppante?
xnor
@xnor accéder à un élément d'une chaîne se fait en wrapper modulo. Donc pas besoin de modulo 2.
Jakube
@xnor Mais merci pour l'inverse. Bien sûr, ce n'est pas nécessaire. (Je suis un peu fatigué aujourd'hui.)
Jakube
16

Perl, 50 45 40 caractères

(Code de 39 caractères + Option de ligne de commande à 1 caractère.)

1while s/\+oe|\+eo|\*oo/o/||s/\W\w\w/e/

Échantillon échantillon:

bash-4.3$ echo -n '**o++*ee*++eoe*eo+eoo' | perl -pe '1while s/\+oe|\+eo|\*oo/o/||s/\W\w\w/e/'
o
homme au travail
la source
Que diriez- while/../vous
primo
Doh. Moi stupide. Effectivement utilisé cette condition tout en essayant sa sedversion… Merci, @primo.
Manatwork
Ou encore mieux, 1while s/\+oe.... Je suis aussi assez sûr que [+*]peut être remplacé par \W.
Primo
Merci encore, @primo. Je pense que je devrais me concentrer sur une seule solution une fois. ( gemame
rend
Même approche avec Sed maintenant 2 octets plus court!
Digital Trauma
13

Rétine , 29 octets

(+`\*oo|\+(eo|oe)
o
\W\w\w
e

Pour la version pratique à un fichier, l' -sindicateur est utilisé.

Nous échangeons des expressions bizarres ( *oo, +oe, +eo) à ojusqu'à 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)

randomra
la source
12

Python 2, 90

def f(s):i=iter(s);a=next(i);return(a>'a')*a or'oe'[f(i)==f(i)if'*'<a else'e'in f(i)+f(i)]

La iterfonction 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 de f. 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 par or'oe'... semble devoir être jouable au golf, mais je n'ai rien trouvé.

-1 grâce à Sp3000.

feersum
la source
Excellente solution! Les fonctions récursives utilisant itervraiment ahurissent mon esprit.
xnor
3
Voici un moyen de calculer l'arithmétique directement avec 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]
xnor
1
@xnor Vous pourriez aussi bien poster cela comme réponse. C'est très différent de cette solution.
Feersum
9

Mathematica, 91 84 octets

#//.s_:>s~StringReplace~{"+ee"|"+oo"|"*ee"|"*eo"|"*oe"->"e","+eo"|"+oe"|"*oo"->"o"}&

Vous cherchez un moyen de compresser cela ...

LegionMammal978
la source
3
//.est plus court que FixedPoint.
Alephalpha
8

Python 2, 80 octets

def f(s,e=0,o=1):i=iter(s);a=next(i);return(a>'a')*a or'eo'[eval(f(i)+a+f(i))%2]

Ceci est construit sur la réponse très intelligente de feersum qui utilise un iterpour implémenter des opérations de notation en polonais. La nouvelle idée est d'utiliser evalpour évaluer les expressions +et *avec eval(f(i)+a+f(i)), où l'opérateur aest placé infixe entre les résultats récursifs. Eval utilise les liaisons e=0,o=1dans les arguments de la fonction optionnelle. La sortie est alors prise mod 2.

Xnor
la source
Cela fonctionne également en python 3. Au fait, comment eval a-t-il besoin des liaisons "e = 0, o = 1"?
Karhell
@karhell Il évalue les expressions comme e+o, il a donc besoin des variables pour faire référence à des nombres.
xnor
8

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.

f(){int c=getchar();return c&4?c:c&1?f()^f()^'e':f()&f();}main(){putchar(f());}
Ruud Helderman
la source
8

Utilitaires Shell + GNU, 33

dc -eFo`rev|tr oe OK`2%p|tr 10 oe

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 remplacer eet opar 0et 1, mais il faudrait alors insérer des espaces pour éviter une analyse gourmande des chiffres en chiffres incorrects.

Au lieu de cela eest remplacé par Kqui est la dccommande pour pousser la précision actuelle à la pile, qui par défaut est 0. Et oest remplacé par Oqui est la dccommande pour pousser la base de sortie actuelle à la pile. Cela doit être étrange, donc nous avons mis 15 avec Foavant 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 maintenant 0et 1, donc, que la base de sortie soit 15. Peu importe, puis est trtraduit en oou e.


J'aime que si vous plissiez les yeux, cette source ressemble presque dc Forever OK.

Trauma numérique
la source
5

Sérieusement , 24 octets

,R'2'e(Æ'1'o(Æ£ƒ'e'o2(%I

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:

,R        get input and reverse it
'2'e(Æ    replace all "e"s with "2"s
'1'o(Æ    replace all "o"s with "1"s
£ƒ        cast as function and call
'e'o2(%I  push "e" if result is even, else "o"
Mego
la source
5

Ruby, 61 octets

Utilisation de l'analyse récursive de descente et de l'algèbre de Boolean.

def f
gets(1)==?+?f^f : ~/\*/?f&f : $_==?o
end
puts f ? ?o:?e

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 retourne truepour impair et falsepour even. 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:

def f
  x = gets(1)
  case x
  when '+'
    f ^ f
  when '*'
    f & f
  else
    x == 'o'
  end
end

puts f ? 'o' : 'e'

Merci à @Shel d'avoir signalé un bogue dans la version initiale.

Daniero
la source
1
Cela ne fonctionne pas, +eedonne o. J'aime l'idée
Shelvacu
remplacer f^favec !f^fet f&favec f|fet cela fonctionne. Programme permettant d'exécuter des
scénarios de
1
Merci, bonne prise! On dirait que je me suis un peu confondu là-bas. Belle suite de test aussi! Le test est la voie à suivre, même en golf :)
daniero
@Shel Aha ..! Je remettais f^fet f&fet retourné $_==?eet à la ?e:?oplace :)
daniero
1
Wow, apprenez quelque chose de nouveau chaque jour ... ruby-doc.org/core/Regexp.html#method-i-7E
Shelvacu
4

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

$o"eo+*"r0I4-[4g1Z2*1F]l*"e"+O.
0f1f+f*f

Essayez ici.

Explication

$o                                Read in whole input as characters
  "eo+*"                          Push these characters onto the stack (in reverse order)
        r                         Reverse the stack
         I4-                      Push the length of the stack - 4
            [                     For loop; pop n and repeat that many times
             4g                   Get the item at the fourth index and put it on top
               1Z                 Pops n and pushes first index of n in stack
                 2*               Multiply by 2
                   1F             Gosub; goes to codebox(2n,1) to be returned to
                     ]            Close for loop
                      l*          Multiply by 10
                        "e"+      Add 101 ("o" is 111)
                            O.    Output as character and stop.
0f1f+f*f                          Does the appropriate operation then returns to F
El'endia Starman
la source
1
Woohoo! bon vieux coq bat une langue (semi-) golfique ;-P
Digital Trauma
4

JavaScript, 110 106 94 octets

while(i.length>2)i=i.replace(/([+*][eo]{2})/,(o,e)=>{return"+oe+eo*oo".indexOf(o)<0?"e":"o"});

Certainement pas la plus petite solution, mais probablement la plus petite solution possible dans un langage aussi prolixe que JavaScript!

Arkain
la source
Utiliser des groupes sans capture est bon pour les performances mais mauvais pour la taille du code. Mieux vaut les supprimer ?:.
manatwork
accepté ... et tellement modifié.
Arkain
A pris un autre regard maintenant. Votre code peut être réduit un peu plus loin 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, alors while(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.
Manatwork
1
Malheureusement, pour être valide sur ce site, nous ne pouvons pas supposer qu’une variable existe déjà. Vous devrez en faire une fonction de, icomme vous l'avez dit.
Alex A.
1
@Arkain, vous n'avez pas besoin de capturer un groupe dans l'expression régulière, car vous utiliserez de toute façon la sous-chaîne correspondante dans son intégralité. Pour la même raison, il n'est pas nécessaire de transmettre le paramètre e au rappel.
Manatwork
4

O , 24 20 19 18 octets

i`2:e;1:o;~2%'o'e?

Prend l'entrée, l'inverse, attribue eà 2 et oà 1 et l' envoie à Tumblr, l' évalue en tant que code O.

Explication:

i` Obtient entrée et inverse, car O utilise la notation postfixe
2: e; Assigne `e` à 2
1: o; Assigne `o` à 1
~ 2% Eval et vérifier si le résultat est pair
'o'e? Sortie 'e' si pair, 'o' si impair
phase
la source
4

GNU Sed, 36

:
s/*oo\|+eo\|+oe/o/
t
s/\W\w\w/e/
t

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\waussi.

Merci à @Ruud pour avoir rasé 4 octets.

Trauma numérique
la source
Avec les parenthèses supprimées, il est maintenant rentable d'abandonner l'expression rationnelle étendue. Vous gagnez 2 octets pour ne pas vous échapper +, vous perdez 2 octets pour vous échapper |, mais le résultat final est que vous gagnez 1 octet pour l'option de largage -r.
Ruud Helderman
@Ruud C'est vrai. Je l'avais déjà essayé, mais je ne réalisais pas |qu'il fallait échapper à la situation quand il -rn'était pas utilisé. Encore 2 octets de plus sur le score - merci!
Traumatismes numériques
2

Haskell, 160 octets

Appel f.

f=until((==1).l)r
r s|l s<3=s|3#s?o=r('o':3%s)|3#s?sequence["+*","oe","oe"]=r('e':3%s)|0<1=1#s++r(1%s)
l=length
(#)=take
(%)=drop
(?)=elem
o=["+eo","+oe","*oo"]
Leif Willerts
la source
2

JavaScript, 92 71 octets

f=i=>i>"0"?i:f(i.replace(/.[eo]{2}/,e=>"eo"[eval((e[1]>"e")+"^&"[+(e[0]<"+")]+(e[2]>"e"))]))

C'est un peu obscurci, mais je voulais faire quelque chose en utilisant evaldes opérateurs au niveau des bits. Annoté:

f = (i) => // function(i) { return
    i>"0"  // i[0] == "o" || i[0] == "e" :-) - the characters `*` and `+` are both <"0"
      ? i  // finish
      : f(i.replace( // recursively repeat with
          /.[eo]{2}/, // first occurrence of "something" followed by two values
          (e) =>    // replaced by
              "eo"[ // string indexing
                eval(
                    (e[1]>"e")        // e[1] == "o" ? "true" : "false"
                  + "^&"[+(e[0]<"+")] // e[0] == "+" ? "^" : "&"
                  + (e[2]>"e")        // e[2] == "o" ? "true" : "false"
                )
              ]     // like eval(…) ? "o" : "e"
        ))

La répétition de (e[…]>"e")m'énerve un peu, mais ce qui suit n'est pas mieux non plus (103 octets):

f=i=>i>"0"?i:f(i.replace(/e|o/g,x=>+(x>"e")).replace(/.\d\d/,e=>"eo"[eval(e[1]+"^&"[+(e[0]<"+")]+e[2])]))

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:

f=i=>i>"0"?i:f(i.replace(/.[eo]{2}/,v=>"eo"[+"+oe+eo*oo".includes(v)]))
Bergi
la source
1

Dart, 173 octets

f(i){var l=i.split(''),e='e',o='o';g(p){if(l[p]!=e&&l[p]!=o){var x=p+1,y=p+2;g(x);g(y);l[p]=l[p]=='+'?l[x]!=l[y]?o:e:l[x]==o?l[y]:e;l.removeRange(x,p+3);}}g(0);print(l[0]);}

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.

pseudo
la source
1

Haskell, 231 octets

Voici une approche utilisant un langage sérieux;)

Version golfée:

p(s:_)[]=s
p s(x:y)=p(r$x:s)y
r[]=[]
r('e':'e':'+':x)=r$'e':x
r('e':'o':'+':x)=r$'o':x
r('o':'e':'+':x)=r$'o':x
r('o':'o':'+':x)=r$'e':x
r('e':'e':'*':x)=r$'e':x
r('e':'o':'*':x)=r$'e':x
r('o':'e':'*':x)=r$'e':x
r('o':'o':'*':x)=r$'o':x
r x=x

Exemple:

*Main> p [] "+**+***+**++**+eooeoeeoeeoeooeo"
'o'

Ungolfed et jolie version complète:

type Stack = String

parse :: String -> Char
parse = parse' []

parse' :: Stack -> String -> Char
parse' (s:_) []     = s
parse' s     (x:xs) = parse' (reduce $ x:s) xs

reduce :: Stack -> Stack
reduce [] = []
reduce ('e':'e':'+':xs) = reduce $ 'e':xs
reduce ('e':'o':'+':xs) = reduce $ 'o':xs
reduce ('o':'e':'+':xs) = reduce $ 'o':xs
reduce ('o':'o':'+':xs) = reduce $ 'e':xs
reduce ('e':'e':'*':xs) = reduce $ 'e':xs
reduce ('e':'o':'*':xs) = reduce $ 'e':xs
reduce ('o':'e':'*':xs) = reduce $ 'e':xs
reduce ('o':'o':'*':xs) = reduce $ 'o':xs
reduce xs               = xs

Exemple:

*Main> parse "+**+***+**++**+eooeoeeoeeoeooeo"
'o'

Caractéristiques: Correspondance des motifs et récursivité.

utilisateur3389669
la source
1

Jolf, 11 octets

(Non compétitif, comme le langage postdate la question.) Essayez-le ici!

FVyAi"oe"@\x12

(Remplacez \x12par le caractère réel \x12. Cela devrait être fait automatiquement dans l'interpréteur.)

Explication:

FVyAi"oe"@\x12
    i          input
          \x12 character 12
         @     char code at
   A "oe"      replace all os with 1s and all es with 2s
  y            eval as jolf, returning the answer
 V             return parity "even" or "odd"
F              get first character
               implicit output
Conor O'Brien
la source
1

Python 3, 171 145 135 octets

Pas 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.

def p(i):
 s=[]
 for c in i[::-1]:
  s+=[c>'e'if c>'a'else getattr(s.pop(),'__'+('axnodr'[c>'*'::2])+'__')(s.pop())]
 return'eo'[s[0]]
Tim Pederick
la source
C'est callable()élégant, mais long. (Inverser la condition et supprimer notseraient plus courts.) Vérifiez plutôt si m est un entier m in[0,1], mais vérifier si c est une valeur c in'eo'serait encore plus court. Ce dernier étant le même que c>'a'dans ce cas.
Manatwork
En réalité, la variable m et ses valeurs numériques ne sont pas nécessaires. Mettez seulement ceci dans for:s+=[c>'e'if c>'a'else{'*':o.and_,'+':o.xor}[c](s.pop(),s.pop())]
manatwork
@manatwork: Merci! Je ne pensais pas pouvoir inverser la situation, car je pensais que cela aurait signifié appeler s.pop()(deux fois) chaque boucle. Je n'ai pas pris la peine de tester jusqu'à maintenant; mais bon, le point est discutable maintenant.
Tim Pederick
Une question me préoccupait depuis le début: pourquoi utiliser le operator module? bool.__and__()et bool.__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())]
Manatwork
@manatwork: Parce que je n'y avais pas pensé. Je n'ai considéré que les opérateurs infixés ( ^, &) et leurs operatorhomologues, en oubliant les méthodes qui les implémentent réellement. Oh, et reversed()a maintenant été abandonné grâce à un autre des conseils de golf Python .
Tim Pederick
1

Haskell, 98 94 octets

Dé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.

p(c:s)|any(<'a')s=p(c:p s)
p('+':x:y:s)|x/=y='o':s
p('*':'o':s)=s
p(c:_:_:s)|c<'a'='e':s
p s=s

Définit une fonction pqui 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:

*Main> p "**o++*ee*++eoe*eo+eoo"
"o"

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.

Ruud Helderman
la source
0

Ajouter ++ , 46 octets

D,g,@,d"oe"$eA"e"=+o
D,f,@,bR€gbU32CjbV2%"eo":

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 fet gest une fonction d'assistance. Nous allons utiliser "*e*o*e*oe"(ce qui est e) à titre d'exemple.

fcommence par prendre la chaîne d'entrée et l'inverser, en cédant "eo*e*o*e*". Nous cartographions gensuite chaque élément:

gcommence 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 pour oet 2 pour e. 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.

caird coinheringaahing
la source