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) * 37
eine 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 e
repräsentiert eine beliebige gerade Zahl und jedes o
repräsentiert eine beliebige ungerade Zahl.
Ihre Aufgabe ist es, den Ausdruck, Druck oder Rückgabe eines einzigen zu vereinfachen e
oder o
basierend 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 e
oder o
oder ein anderes +
oder ein *
Ausdruck sein, der wiederum Operanden enthält.
Beispielsweise *+eoo
könnte die Eingabe als mul(add(e, o), o)
oder (e + o) * o
in normaler Infixnotation gelesen werden . Das e
und das erste o
sind die Operanden, die dem entsprechen +
, +eo
und das letzte o
sind 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 e
gerade oder o
ungerade 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
quelle
eval
OK?Antworten:
CJam,
181713 BytesDanke an aditsu für das Speichern von 4 Bytes.
Probieren Sie die Testsuite hier aus. (Die Testsuite ist zu lang für den Permalink. Kopieren Sie sie einfach aus der Herausforderungsspezifikation.)
Erläuterung
quelle
Pyth,
16 bis14 BytesPyth kann selbst einen String in Pyth-Syntax auswerten. Deshalb ersetze ich
e
undo
mit4
und5
. 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:
Zusätzliche Erklärung zum Ersetzen.
G
ist eine mit dem Alphabet initialisierte Variableabc...xyz
.U9
ist die Liste[0, 1, ..., 8]
.XzGU9
Ersetzt die Buchstaben des Alphabets durch die Werte der Liste. Alsoa
wird ersetzt durch0
,b
mit1
, ...,e
mit4
, ...,i
mit8
,j
mit0
, ... undo
mit5
. Deshalb werde iche
durch eine gerade undo
eine ungerade Zahl ersetzt. Alle anderen Ersetzungen haben überhaupt keine Wirkung.quelle
Perl,
504540 Zeichen(39 Zeichen Code + 1 Zeichen Befehlszeilenoption.)
Probelauf:
quelle
while/../
?sed
Habe diese Bedingung tatsächlich verwendet, während ich ihre Version ausprobiert habe ... Danke, @primo.1while s/\+oe...
. Ich bin mir auch ziemlich sicher,[+*]
dass durch ersetzt werden kann\W
.gema
mich wahnsinnig ...)Retina , 29 Bytes
Für die praktische Version mit einer Datei wird das
-s
Flag verwendet.Wir tauschen ungerade Ausdrücke (
*oo
,+oe
,+eo
) zu ,o
bis wir können, dann tauschen Sie die restlichen Symbol-Buchstaben-Buchstaben - Ausdrückene
. 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)
quelle
Python 2, 90
Die
iter
Funktion 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 wurdef
. 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 mitor'oe'
... beginnt, scheint golfen zu können, aber ich konnte nichts finden.-1 dank Sp3000.
quelle
iter
verwirren mich wirklich.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 BytesAuf der Suche nach einer Möglichkeit, dies zu komprimieren ...
quelle
//.
ist kürzer alsFixedPoint
.Python 2, 80 Bytes
Dies wird auf feersum eingebaute sehr kluge Antwort , die eine verwendeten
iter
polnisch-Notation Operationen zu implementieren. Die neue Idee besteht darineval
, die Ausdrücke auszuwerten+
und*
miteval(f(i)+a+f(i))
, wo der Operatora
zwischen den rekursiven Ergebnissen eingefügt wird. Das eval verwendet die Bindungene=0,o=1
in den optionalen Funktionsargumenten. Die Ausgabe erfolgt dann mod 2.quelle
e+o
und benötigt daher die Variablen, um sich auf Zahlen zu beziehen.C 79 Bytes
Einfache Rekursion. Beruht auf einigen (zufälligen?) Bitweisen Eigenschaften der vier zulässigen Eingabezeichen.
quelle
Shell + GNU-Dienstprogramme, 33
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önntene
undo
durch0
und ersetzen1
, aber dann müssten Leerzeichen eingefügt werden, um ein gieriges Parsen der Ziffern in die falschen Zahlen zu verhindern.Stattdessen
e
wird ersetzt durchK
dendc
Befehl zum Übertragen der aktuellen Genauigkeit zum Stapel, der standardmäßig 0 ist. Undo
wird ersetzt durchO
dendc
Befehl zum Übertragen der aktuellen Ausgabebasis zum Stapel. Dies muss ungerade sein, also setzen wir es mit auf 15,Fo
bevor 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 now0
und1
, es spielt also keine Rolle, dass die Ausgabebasis 15 ist. Dann wirdtr
zurück ino
oder übersetzte
.Ich mag es, wenn du deine Augen zusammenknickst, diese Quelle sieht fast so aus
dc Forever OK
.quelle
Im Ernst , 24 Bytes
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:
quelle
Ruby, 61 Bytes
Verwenden von Parsing rekursiver Abstammung und Boolescher Algebra.
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 gibttrue
für ungerade undfalse
für zurückeven
. Die^
XOR- und&
AND- Operatoren werden verwendet, um die "Seltsamkeit" von Additions- bzw. Multiplikationsausdrücken zu bestimmen.Hier ist eine ungolfed Version:
Vielen Dank an @Shel für den Hinweis auf einen Fehler in der ursprünglichen Version.
quelle
+ee
gibto
. Ich mag die Ideef^f
mit!f^f
undf&f
mitf|f
und es funktioniert. Programm auszuführen Testfälle: pastebin.com/ufXfd1vcf^f
undf&f
und drehte$_==?e
und?e:?o
stattdessen :)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
Probieren Sie es hier aus.
Erläuterung
quelle
JavaScript,
110 10694 BytesMit Sicherheit nicht die kleinste Lösung, aber wahrscheinlich die kleinste Lösung, die in einer ausführlichen Sprache wie JavaScript möglich ist!
quelle
?:
.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, dannwhile(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.i
wie Sie sagten.O ,
24201918 BytesNimmt die Eingabe, kehrt es weist
e
auf 2 undo
auf 1 und trägtihn zu Tumblres als O - Code auswertet.Erläuterung:
quelle
GNU Sed, 36
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.
quelle
+
, Sie verlieren 2 Bytes für das Escape|
, aber das Endergebnis ist, dass Sie 1 Byte für die Drop-Option gewinnen-r
.|
, dass es notwendig-r
ist , zu entkommen, wenn es nicht verwendet wird. Noch 2 Bytes weniger - danke!Haskell, 160 Bytes
Rufen Sie an
f
.quelle
JavaScript,
9271 BytesEs ist ein bisschen verschleiert, aber ich wollte etwas mit
eval
und bitweisen Operatoren machen. Kommentiert:Die Wiederholung von
(e[…]>"e")
ärgert mich ein bisschen, aber das Folgende ist auch nicht besser (103 Bytes):Letztendlich ist der Ansatz von @ Arkain mit einfachem Teilstring-Matching überlegen. Mit einigen Optimierungen zu einer Funktion gemacht:
quelle
Dart, 173 Bytes
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.
quelle
Haskell, 231 Bytes
Hier ist ein Ansatz mit einer seriösen Sprache;)
Golf Version:
Beispiel:
Ungolfed und ziemlich umfassende Version:
Beispiel:
Features: Pattern Matching und Rekursion.
quelle
Jolf, 11 Bytes
(Nicht konkurrenzfähig, da die Sprache die Frage datiert.) Probieren Sie es hier aus!
(Ersetzen Sie
\x12
durch das tatsächliche Zeichen\x12
. Dies sollte automatisch im Interpreter erfolgen.)Erläuterung:
quelle
Python 3,
171145135 BytesNicht 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.
quelle
callable()
ist elegant, aber lang. (Das Umkehren der Bedingung und das Entfernennot
wären kürzer.) Überprüfen Sie stattdessen, ob m eine Ganzzahlm in[0,1]
ist, aber ob c ein Wert ist,c in'eo'
wäre noch kürzer. Dies ist später dasselbe wiec>'a'
in diesem Fall.for
:s+=[c>'e'if c>'a'else{'*':o.and_,'+':o.xor}[c](s.pop(),s.pop())]
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.operator
Modul verwenden?bool.__and__()
undbool.__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 werdens+=[c>'e'if c>'a'else getattr(s.pop(),'__'+('axnodr'[c>'*'::2])+'__')(s.pop())]
.^
,&
) und ihreoperator
Gegenstücke betrachtet und dabei die Methoden vergessen, die sie tatsächlich implementieren. Oh, undreversed()
ist jetzt dank eines weiteren Python-Golftipps fallengelassen worden .Haskell,
9894 BytesEs 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.
Definiert eine Funktion
p
, die einen gültigen Ausdruck als Parameter akzeptiert und das Ergebnis als Zeichenfolge der Länge 1 zurückgibt.Beispiel:
Die Funktion reduziert wiederholt den Operator ganz rechts in der Zeichenfolge, bis keine Operatoren mehr übrig sind.
quelle
Add ++ , 46 Bytes
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
f
undg
ist eine Hilfsfunktion. Wir werden"*e*o*e*oe"
(was iste
) als Beispiel verwenden.f
Beginnt damit, die Eingabezeichenfolge zu nehmen und sie umzukehren"eo*e*o*e*"
. Wir bilden danng
jedes Element ab:g
Beginnt 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üro
und 2 füre
. 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.quelle