Nun, das ist seltsam ... nein, warte, das ist gerade!


70

Präambel

Ganzzahlen sind immer entweder gerade oder ungerade . Gerade ganze Zahlen sind durch zwei teilbar, ungerade ganze Zahlen nicht.

Wenn Sie zwei Ganzzahlen hinzufügen, können Sie ableiten, ob das Ergebnis gerade oder ungerade ist, je nachdem, ob die Summanden gerade oder ungerade waren:

  • Gerade + Gerade = Gerade
  • Gerade + Ungerade = Ungerade
  • Ungerade + Gerade = Ungerade
  • Ungerade + Ungerade = Gerade

Wenn Sie zwei Ganzzahlen multiplizieren, können Sie auch ableiten, ob das Ergebnis gerade oder ungerade ist, je nachdem, ob die Faktoren gerade oder ungerade waren:

  • Gerade * Gerade = Gerade
  • Gerade * Ungerade = Gerade
  • Ungerade * Gerade = Gerade
  • Ungerade * Ungerade = Ungerade

Wenn Sie also die Gleichmäßigkeit oder Ungleichmäßigkeit aller Variablen in einem mathematischen Ausdruck kennen, bei dem es nur um Addition und Multiplikation geht, können Sie ableiten, ob das Ergebnis gerade oder ungerade ist.

Zum Beispiel können wir zuversichtlich sagen, dass dies (68 + 99) * 37eine Ungerade ergibt, weil ein gerades Plus eine ungerade ( 68 + 99) eine ungerade ist, und dass ungerade mal eine andere ungerade ( odd * 37) eine ungerade ergibt.

Herausforderung

Schreiben Sie ein Programm oder eine Funktion, die nur eine Zeichenfolge mit den vier Zeichen enthält eo+*. Diese Zeichenfolge stellt einen mathematischen Ausdruck dar, der in Präfixnotation angegeben wird und nur Addition ( +) und Multiplikation ( *) umfasst. Jedes erepräsentiert eine beliebige gerade Zahl und jedes orepräsentiert eine beliebige ungerade Zahl.

Ihre Aufgabe ist es, den Ausdruck, Druck oder Rückgabe eines einzigen zu vereinfachen eoder obasierend darauf , ob das Ergebnis des Ausdrucks gerade oder ungerade ist .

Sie können davon ausgehen, dass die Eingabe immer in gültiger Präfixnotation erfolgt. Insbesondere werden hinter jedem +und *immer zwei entsprechende Operanden vorkommen. Diese Operanden können ein einzelnes eoder ooder ein anderes +oder ein *Ausdruck sein, der wiederum Operanden enthält.

Beispielsweise *+eookönnte die Eingabe als mul(add(e, o), o)oder (e + o) * oin normaler Infixnotation gelesen werden . Das eund das erste osind die Operanden, die dem entsprechen +, +eound das letzte osind die Operanden, die dem entsprechen *.

Zur Verdeutlichung hier einige ungültige Eingaben mit falscher Präfixnotation:

eo
ooe
o+e
ee*
+*oe
+e*o

Eine einzelne nachgestellte Zeile in der Ausgabe ist in Ordnung, ansonsten sollte nur eine egerade oder oungerade Zeile ausgegeben werden.

Der kürzeste Code in Bytes gewinnt.

Testfälle

(Leerzeilen dienen nur zur optischen Trennung ähnlicher Fälle.)

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

8
Können wir 1 und 0 anstelle von e und o als Eingabe nehmen?
ghosts_in_the_code

8
@ghosts_in_the_code Nein, sorry.
Calvins Hobbys

2
Verwendet evalOK?
xnor

1
@ Xnor sicher. Was auch immer funktioniert.
Calvins Hobbys

2
Ich bezweifle, dass ich dies verwenden kann, um die bereits geposteten 13 Bytes zu schlagen, aber ich stelle fest, dass die Addition einem exklusiven oder und die Multiplikation einem einfachen oder entspricht.
WGroleau

Antworten:


43

CJam, 18 17 13 Bytes

Danke an aditsu für das Speichern von 4 Bytes.

qW:O%eu~"eo"=

Probieren Sie die Testsuite hier aus. (Die Testsuite ist zu lang für den Permalink. Kopieren Sie sie einfach aus der Herausforderungsspezifikation.)

Erläuterung

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.

27

Pyth, 16 bis 14 Bytes

@"eo".vjdXzGU9

Pyth kann selbst einen String in Pyth-Syntax auswerten. Deshalb ersetze ich eund omit 4und 5. Die Auswertung gibt mir dann eine gerade oder ungerade Zahl und ich kann das Ergebnis leicht ausdrucken.

Probieren Sie es online aus: Demo oder Test Suite

Erläuterung:

@"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"

Zusätzliche Erklärung zum Ersetzen. Gist eine mit dem Alphabet initialisierte Variable abc...xyz. U9ist die Liste [0, 1, ..., 8]. XzGU9Ersetzt die Buchstaben des Alphabets durch die Werte der Liste. Also awird ersetzt durch 0, bmit 1, ..., emit 4, ..., imit 8, jmit 0, ... und omit 5. Deshalb werde ich edurch eine gerade und oeine ungerade Zahl ersetzt. Alle anderen Ersetzungen haben überhaupt keine Wirkung.


Warum kehren Sie den Ausdruck um? Müssen Sie auch nicht das Ergebnis modulo 2 nehmen, oder läuft die Indizierung rund?
xnor

Der Zugriff auf ein Element in einem String erfolgt durch Modulo-Wrapping. Also keine Notwendigkeit für Modulo 2.
Jakube

@xnor Aber danke für die umgekehrte Sache. Das ist natürlich nicht nötig. (Ich bin heute ein bisschen müde.)
Jakube

16

Perl, 50 45 40 Zeichen

(39 Zeichen Code + 1 Zeichen Befehlszeilenoption.)

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

Probelauf:

bash-4.3$ echo -n '**o++*ee*++eoe*eo+eoo' | perl -pe '1while s/\+oe|\+eo|\*oo/o/||s/\W\w\w/e/'
o

Wie wäre es while/../?
Primo

Doh. Ich bin dumm. sedHabe diese Bedingung tatsächlich verwendet, während ich ihre Version ausprobiert habe ... Danke, @primo.
Handarbeit

Oder noch besser 1while s/\+oe.... Ich bin mir auch ziemlich sicher, [+*]dass durch ersetzt werden kann \W.
Primo

Nochmals vielen Dank, @primo. Ich denke, ich sollte mich einmal auf eine einzige Lösung konzentrieren. (macht gemamich wahnsinnig ...)
manatwork

Gleicher Ansatz mit Sed jetzt 2 Bytes kürzer!
Digital Trauma

13

Retina , 29 Bytes

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

Für die praktische Version mit einer Datei wird das -sFlag verwendet.

Wir tauschen ungerade Ausdrücke ( *oo, +oe, +eo) zu , obis wir können, dann tauschen Sie die restlichen Symbol-Buchstaben-Buchstaben - Ausdrücken e. Wir wiederholen dies, bis wir können und der letzte Buchstabe unsere Ausgabe ist.

(Diese Lösung ähnelt der Perl-Antwort von manatwork .)

Probieren Sie es online! (von Dennis)


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)]

Die iterFunktion ist eine gute Möglichkeit, die Eingabezeichenfolge in eine FIFO-Warteschlange zu verwandeln, die sich daran erinnert, wie viel der Zeichenfolge über Aufrufe von analysiert wurde f. Es ist idempotent, daher ist es harmlos, es erneut aufzurufen, wenn die Eingabe bereits ein Iterator und keine Zeichenfolge ist. Die hintere Hälfte der Antwort, die mit or'oe'... beginnt, scheint golfen zu können, aber ich konnte nichts finden.

-1 dank Sp3000.


Tolle Lösung! Rekursive Funktionen iterverwirren mich wirklich.
2.

3
Hier ist eine Möglichkeit, die Arithmetik direkt zu berechnen 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 Du kannst das genauso gut als Antwort posten. Es unterscheidet sich sehr von dieser Lösung.
Feersum

9

Mathematica, 91 84 Bytes

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

Auf der Suche nach einer Möglichkeit, dies zu komprimieren ...


3
//.ist kürzer als FixedPoint.
Alephalpha

8

Python 2, 80 Bytes

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]

Dies wird auf feersum eingebaute sehr kluge Antwort , die eine verwendeten iterpolnisch-Notation Operationen zu implementieren. Die neue Idee besteht darin eval, die Ausdrücke auszuwerten +und *mit eval(f(i)+a+f(i)), wo der Operator azwischen den rekursiven Ergebnissen eingefügt wird. Das eval verwendet die Bindungen e=0,o=1in den optionalen Funktionsargumenten. Die Ausgabe erfolgt dann mod 2.


Dies funktioniert auch in Python 3. Wie braucht eval übrigens die Bindungen "e = 0, o = 1"?
Karhell

@karhell Es wertet Ausdrücke wie aus e+ound benötigt daher die Variablen, um sich auf Zahlen zu beziehen.
Xnor

8

C 79 Bytes

Einfache Rekursion. Beruht auf einigen (zufälligen?) Bitweisen Eigenschaften der vier zulässigen Eingabezeichen.

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

8

Shell + GNU-Dienstprogramme, 33

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

Die Eingabe erfolgt über STDIN.

Dies macht den gleichen Trick wie das Umkehren der Eingabe und das Auswerten mit einem stapelbasierten Rechner - in diesem Fall dc. Wir könnten eund odurch 0und ersetzen 1, aber dann müssten Leerzeichen eingefügt werden, um ein gieriges Parsen der Ziffern in die falschen Zahlen zu verhindern.

Stattdessen ewird ersetzt durch Kden dcBefehl zum Übertragen der aktuellen Genauigkeit zum Stapel, der standardmäßig 0 ist. Und owird ersetzt durch Oden dcBefehl zum Übertragen der aktuellen Ausgabebasis zum Stapel. Dies muss ungerade sein, also setzen wir es mit auf 15, Fobevor wir etwas anderes in dc machen.

Dann geht es einfach darum, Mod 2 zu nehmen und zu drucken 2%p. Die einzig möglichen Werte sind now 0und 1, es spielt also keine Rolle, dass die Ausgabebasis 15 ist. Dann wird trzurück in ooder übersetzt e.


Ich mag es, wenn du deine Augen zusammenknickst, diese Quelle sieht fast so aus dc Forever OK.


5

Im Ernst , 24 Bytes

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

Effizientere Stack-Manipulationen könnten das wahrscheinlich kürzer machen, aber ich bin zufrieden damit.

Nimmt Eingaben als Zeichenfolge wie "+*oee"

Online ausprobieren (Eingabe muss manuell erfolgen)

Erläuterung:

,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"

5

Ruby, 61 Bytes

Verwenden von Parsing rekursiver Abstammung und Boolescher Algebra.

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

Die Funktion liest jeweils ein Zeichen von stdin. Wenn es a +oder a liest *, ruft es sich zweimal auf, um ungerade oder gerade zu bestimmen. Die Funktion gibt truefür ungerade und falsefür zurück even. Die ^ XOR- und & AND- Operatoren werden verwendet, um die "Seltsamkeit" von Additions- bzw. Multiplikationsausdrücken zu bestimmen.

Hier ist eine ungolfed Version:

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

puts f ? 'o' : 'e'

Vielen Dank an @Shel für den Hinweis auf einen Fehler in der ursprünglichen Version.


1
Das geht nicht, +eegibt o. Ich mag die Idee
Shelvacu

Ersetzen f^fmit !f^fund f&fmit f|fund es funktioniert. Programm auszuführen Testfälle: pastebin.com/ufXfd1vc
Shelvacu

1
Danke, guter Fang! Scheint, als hätte ich mich ein bisschen verwirrt. Schöne Testsuite auch! Probefahren ist der
richtige

@Shel Aha ..! Ich wechselte zurück f^fund f&fund drehte $_==?eund ?e:?ostattdessen :)
Daniero

1
Wow, lerne jeden Tag etwas Neues ... ruby-doc.org/core/Regexp.html#method-i-7E
Shelvacu

4

Minkolang 0,14 , 40 Bytes

Ich habe versucht, eine clevere Bewertungsmethode anzuwenden, aber es hat sich herausgestellt, dass der Programmzähler keine Werte erreicht, die der Codebox außerhalb des ursprünglichen Bereichs hinzugefügt wurden. Also habe ich eine weniger clevere Bewertungsmethode angewendet. : P

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

Probieren Sie es hier aus.

Erläuterung

$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

1
Woohoo! Die gute alte Muschel schlägt eine (halb-) Golfsprache ;-P
Digital Trauma

4

JavaScript, 110 106 94 Bytes

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

Mit Sicherheit nicht die kleinste Lösung, aber wahrscheinlich die kleinste Lösung, die in einer ausführlichen Sprache wie JavaScript möglich ist!


Die Verwendung von nicht erfassenden Gruppen wirkt sich positiv auf die Leistung aus, jedoch negativ auf die Codegröße. Besser diese entfernen ?:.
Handarbeit

einverstanden ... und so modifiziert.
Arkain

Habe jetzt einen anderen Blick darauf geworfen. Ihr Code kann etwas weiter reduziert werden while(i.length>2)i=i.replace(/[+*][eo]{2}/,function(o){return"+oe+eo*oo".indexOf(o)>=0?"o":"e"}). Oder wenn Sie zur Fettpfeil-Funktion von ECMAScript 6 wechseln, dann while(i.length>2)i=i.replace(/[+*][eo]{2}/,o=>"+oe+eo*oo".indexOf(o)>=0?"o":"e"). Aber leider besagt die Anforderung "Programm" oder "Funktion", während Ihr aktueller Code ein Ausschnitt ist. Es sollte entweder Eingabe und Ausgabe oder Argument und Rückgabewert verarbeiten.
Handarbeit

1
Um auf dieser Site gültig zu sein, können wir leider nicht davon ausgehen, dass bereits eine Variable existiert. Sie müssen es zu einer Funktion machen, iwie Sie sagten.
Alex A.

1
@Arkain, Sie müssen im regulären Ausdruck keine Gruppe erfassen, da Sie die gesamte übereinstimmende Teilzeichenfolge ohnehin als ein Teil verwenden. Aus dem gleichen Grund muss der Parameter e nicht an den Callback übergeben werden.
Manatwork

4

O , 24 20 19 18 Bytes

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

Nimmt die Eingabe, kehrt es weist eauf 2 und oauf 1 und trägt ihn zu Tumblr es als O - Code auswertet.

Erläuterung:

i` Holen Sie sich die Eingabe und kehren Sie sie um, da O die Postfix-Notation verwendet
2: e; Weisen Sie "e" zu 2
1: o; Weisen Sie "o" 1 zu
~ 2% Auswerten und überprüfen, ob das Ergebnis gerade ist
'o'e? Geben Sie 'e' aus, wenn gerade, 'o', wenn ungerade

4

GNU Sed, 36

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

Nach der Buchung habe ich diesen genau den gleichen Ansatz wie @ Manatwork Perl Antwort und Retina des @ randomra Antwort . Ich schätze, ich kann genauso gut den ganzen Weg gehen und sie auch ausleihen \W\w\w.

Vielen Dank an @Ruud für das Abschneiden von 4 Bytes.


Wenn die Klammern weg sind, lohnt es sich jetzt, auf erweiterte reguläre Ausdrücke zu verzichten. Sie gewinnen 2 Bytes für das Nicht-Escape +, Sie verlieren 2 Bytes für das Escape |, aber das Endergebnis ist, dass Sie 1 Byte für die Drop-Option gewinnen -r.
Ruud Helderman

@Ruud Das stimmt. Ich habe es bereits versucht, aber nicht erkannt |, dass es notwendig -rist , zu entkommen, wenn es nicht verwendet wird. Noch 2 Bytes weniger - danke!
Digital Trauma

2

Haskell, 160 Bytes

Rufen Sie an 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"]

2

JavaScript, 92 71 Bytes

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

Es ist ein bisschen verschleiert, aber ich wollte etwas mit evalund bitweisen Operatoren machen. Kommentiert:

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"
        ))

Die Wiederholung von (e[…]>"e")ärgert mich ein bisschen, aber das Folgende ist auch nicht besser (103 Bytes):

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])]))

Letztendlich ist der Ansatz von @ Arkain mit einfachem Teilstring-Matching überlegen. Mit einigen Optimierungen zu einer Funktion gemacht:

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

1

Dart, 173 Bytes

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]);}

Das ist nicht wettbewerbsfähig, aber was auch immer. Der Kern der Lösung besteht darin, beginnend mit 0 jeden Operator rekursiv durch die Auswertung des diesem Operator folgenden Zeichenpaars zu ersetzen und diese Zeichen dann aus der Liste zu entfernen.


1

Haskell, 231 Bytes

Hier ist ein Ansatz mit einer seriösen Sprache;)

Golf Version:

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

Beispiel:

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

Ungolfed und ziemlich umfassende Version:

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

Beispiel:

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

Features: Pattern Matching und Rekursion.


1

Jolf, 11 Bytes

(Nicht konkurrenzfähig, da die Sprache die Frage datiert.) Probieren Sie es hier aus!

FVyAi"oe"@\x12

(Ersetzen Sie \x12durch das tatsächliche Zeichen \x12. Dies sollte automatisch im Interpreter erfolgen.)

Erläuterung:

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

1

Python 3, 171 145 135 Bytes

Nicht wettbewerbsfähig, aber ich hatte Spaß daran, also konnte ich es einfach nicht für mich behalten. Im Gegensatz zum (sehr cleveren) rekursiven Iterator-Python-Eintrag von feersum kehrt dieser die Eingabe um und führt dann ein gutes altes stapelbasiertes Parsen der umgekehrten polnischen Notation durch.

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]]

Das callable()ist elegant, aber lang. (Das Umkehren der Bedingung und das Entfernen notwären kürzer.) Überprüfen Sie stattdessen, ob m eine Ganzzahl m in[0,1]ist, aber ob c ein Wert ist, c in'eo'wäre noch kürzer. Dies ist später dasselbe wie c>'a'in diesem Fall.
Manatwork

Tatsächlich ist die Variable m und ihre numerischen Werte nicht erforderlich. Setzen Sie nur dieses in das for:s+=[c>'e'if c>'a'else{'*':o.and_,'+':o.xor}[c](s.pop(),s.pop())]
manatwork

@manatwork: Danke! Ich hätte nicht gedacht, dass ich den Zustand umkehren könnte, weil ich dachte, dass das s.pop()(zweimal) Aufrufen jeder Schleife bedeutet hätte. Ich habe mich bis jetzt nicht um Tests gekümmert. aber hey, der Punkt ist jetzt strittig.
Tim Pederick

Eine Frage hat mich von Anfang an gestört: Warum das operator Modul verwenden? bool.__and__()und bool.__xor__()sind handlicher: s+=[c>'e'if c>'a'else getattr(s.pop(),{'*':'__and__','+':'__xor__'}[c])(s.pop())]. Aber basierend auf gnibbler ‚s Slicing Spitze , kann man erkennen, in geändert werden s+=[c>'e'if c>'a'else getattr(s.pop(),'__'+('axnodr'[c>'*'::2])+'__')(s.pop())].
Handarbeit

@manatwork: Weil ich nicht daran gedacht hatte. Ich habe nur die Infix-Operatoren ( ^, &) und ihre operatorGegenstücke betrachtet und dabei die Methoden vergessen, die sie tatsächlich implementieren. Oh, und reversed()ist jetzt dank eines weiteren Python-Golftipps fallengelassen worden .
Tim Pederick

1

Haskell, 98 94 Bytes

Es tut mir leid, Sie mit einem weiteren Versuch von Haskell zu belästigen. wollte nur beweisen, dass es in weniger als 100 Bytes sehr gut möglich ist.

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

Definiert eine Funktion p, die einen gültigen Ausdruck als Parameter akzeptiert und das Ergebnis als Zeichenfolge der Länge 1 zurückgibt.

Beispiel:

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

Die Funktion reduziert wiederholt den Operator ganz rechts in der Zeichenfolge, bis keine Operatoren mehr übrig sind.


0

Add ++ , 46 Bytes

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

Probieren Sie es online!

In der Fußzeile werden einfach alle Beispieleingaben und ihre entsprechenden Ausgaben aufgelistet.

Wie es funktioniert

Wie ein Verlust der Antworten hier, verwendet dies Ersatz und Bewertung. Unsere Hauptfunktion ist fund gist eine Hilfsfunktion. Wir werden "*e*o*e*oe"(was ist e) als Beispiel verwenden.

fBeginnt damit, die Eingabezeichenfolge zu nehmen und sie umzukehren "eo*e*o*e*". Wir bilden dann gjedes Element ab:

gBeginnt mit dem Duplizieren des Arguments, um eine Kopie bis zum letzten Befehl aufzubewahren. Wir prüfen dann, ob das Argument in der Zeichenfolge enthalten ist "oe", und geben 1 für Buchstaben und 0 für *oder +. Wir drücken dann das Argument erneut und prüfen, ob es gleich ist "e". Dieses Ergebnis wird dann zur vorherigen Prüfung hinzugefügt. Dies ergibt 0 für entweder *oder +, 1 für ound 2 für e. Wir nehmen dann das logische ODER zwischen diesem Wert und dem Argument. Wenn der Wert 0 ist , wird er durch das Argument (dh *oder +) ersetzt, andernfalls bleibt er unverändert (dh 1 und 2 ).

Dies konvertiert alle Buchstaben in der Umkehrung der Eingabe in einen numerischen Wert. Wir verbinden dann jedes Element durch Leerzeichen, um sicherzustellen, dass die Ziffern nicht verkettet werden. In unserem Beispiel ergibt dies die Zeichenfolge "2 1 * 2 * 1 * 2 *". Wir können dies dann unter Verwendung der Postfix-Notation von Add ++ auswerten, was 8 ergibt . Wir nehmen dann die Parität dieses Werts und ergeben entweder 0 für gerade Zahlen und 1 für ungerade Zahlen, bevor wir in die Zeichenfolge indexieren "eo"und den entsprechenden Buchstaben zurückgeben.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.