Preambuła
Liczby całkowite są zawsze parzyste lub nieparzyste . Nawet liczby całkowite są podzielne przez dwa, nieparzyste liczby całkowite nie są.
Po dodaniu dwóch liczb całkowitych możesz wywnioskować, czy wynik będzie parzysty czy nieparzysty na podstawie tego, czy sumy były parzyste czy nieparzyste:
- Parzysty + Parzysty = Parzysty
- Parzysty + Nieparzysty = Nieparzysty
- Nieparzysty + Parzysty = Nieparzysty
- Nieparzysty + Nieparzysty = Parzysty
Podobnie, mnożąc dwie liczby całkowite, możesz wywnioskować, czy wynik będzie parzysty czy nieparzysty na podstawie tego, czy czynniki były parzyste czy nieparzyste:
- Parzysty * Parzysty = Parzysty
- Parzysty * Nieparzysty = Parzysty
- Nieparzysty * Parzysty = Parzysty
- Nieparzysty * Nieparzysty = Nieparzysty
Zatem jeśli znasz równość lub nieparzystość wszystkich zmiennych w wyrażeniu matematycznym, które obejmuje tylko dodawanie i mnożenie, możesz wywnioskować, czy wynik będzie parzysty czy nieparzysty.
Na przykład możemy śmiało powiedzieć, że (68 + 99) * 37
wynikiem jest nieparzysty, ponieważ parzysty plus nieparzysty ( 68 + 99
) jest nieparzysty, a ten razy nieparzysty inny nieparzysty ( odd * 37
) daje nieparzysty.
Wyzwanie
Napisz program lub funkcję, która pobiera ciąg zawierający tylko cztery znaki eo+*
. Ten ciąg reprezentuje wyrażenie matematyczne podane w notacji przedrostkowej obejmującej tylko dodawanie ( +
) i mnożenie ( *
). Każda e
reprezentuje dowolną liczbę parzystą, a każda o
reprezentuje dowolną liczbę nieparzystą.
Twoim zadaniem jest uproszczenie wyrażenia, drukowanie lub powrotu pojedynczy e
lub o
na podstawie tego, czy wynikiem wyrażenia jest parzyste, czy nieparzyste.
Możesz założyć, że dane wejściowe zawsze będą miały poprawną notację przedrostkową. W szczególności, każdy +
i *
zawsze będzie miał dwa odpowiadające operandy występujące po nim. Te argumenty mogą być pojedyncze e
lub o
lub inny +
albo *
wyrażenie, które z kolei ma argumentów.
Na przykład dane wejściowe *+eoo
można odczytać jako mul(add(e, o), o)
lub (e + o) * o
w normalnej notacji infiksowej . Pierwszy e
i pierwszy o
to operandy odpowiadające +
, a +eo
ostatni o
to operandy odpowiadające *
.
Aby to wyjaśnić, oto niektóre niepoprawne dane wejściowe, które mają niepoprawny zapis prefiksu:
eo
ooe
o+e
ee*
+*oe
+e*o
Pojedynczy znak nowej linii na wyjściu jest w porządku, ale poza tym wszystko, co powinno być wyprowadzone , to zwykły e
parzysty lub o
nieparzysty.
Najkrótszy kod w bajtach wygrywa.
Przypadki testowe
(Puste wiersze służą jedynie do wizualnego oddzielenia podobnych przypadków.)
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
źródło
eval
OK?Odpowiedzi:
CJam,
181713 bajtówDzięki aditsu za oszczędność 4 bajtów.
Wypróbuj pakiet testowy tutaj. (Pakiet testowy jest za długi na permalink. Po prostu skopiuj go ze specyfikacji wyzwania).
Wyjaśnienie
źródło
Pyth
1614 bajtówPyth może sam ocenić ciąg znaków, który jest w składni Pyth. Dlatego wymieniam
e
io
z4
a5
. Następnie ocena da mi parzystą lub nieparzystą liczbę i mogę łatwo wydrukować wynik.Wypróbuj online: pakiet demonstracyjny lub testowy
Wyjaśnienie:
Dodatkowe objaśnienie do zamiany.
G
jest zmienną zainicjowaną alfabetemabc...xyz
.U9
jest lista[0, 1, ..., 8]
.XzGU9
zastępuje litery alfabetu wartościami listy. Więca
zostaje zastąpiony przez0
,b
z1
, ...,e
z4
, ...,i
z8
,j
z0
, ... io
z5
. Dlatego zostałeme
zastąpiony liczbą parzystą io
liczbą nieparzystą. Wszystkie pozostałe zamienniki nie mają żadnego efektu.źródło
Perl,
504540 znaków(Kod 39 znaków + opcja wiersza poleceń 1 znak.)
Przykładowy przebieg:
źródło
while/../
?sed
wersji… Dziękuję, @primo.1while s/\+oe...
. Jestem również pewien, że[+*]
można go zastąpić\W
.gema
doprowadza mnie do szaleństwa…)Siatkówka , 29 bajtów
Dla wygodnej wersji jednego pliku
-s
używana jest flaga.Możemy zamienić wyrazy nieparzyste (
*oo
,+oe
,+eo
) doo
momentu możemy, a następnie zamienić pozostałych wyrażeń symbol-letter list doe
. Powtarzamy to, dopóki nie możemy, a ostatnia litera jest naszym wynikiem.(To rozwiązanie jest podobne do odpowiedzi Perla dla manatwork .)
Wypróbuj online! (autor: Dennis)
źródło
Python 2, 90
Ta
iter
funkcja jest dobrym sposobem przekształcenia łańcucha wejściowego w kolejkę FIFO, która zapamiętuje, ile łańcucha zostało przeanalizowane przez wywołaniaf
. Jest idempotentny, więc wywoływanie go, gdy wejście jest już iteratorem, a nie ciągiem, jest niegroźne. Końcowa połowa odpowiedzi zaczynająca się odor'oe'
... wydaje się, że powinna być możliwa do gry w golfa, ale nic nie mogłem znaleźć.-1 dzięki Sp3000.
źródło
iter
naprawdę oszałamia mój umysł.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 bajtówSzukasz sposobu na skompresowanie tego ...
źródło
//.
jest krótszy niżFixedPoint
.Python 2, 80 bajtów
Jest to oparte na bardzo sprytnej odpowiedzi Feersum, która wykorzystuje
iter
do implementacji operacji notacji polskiej. Nowym pomysłem jest użycieeval
do oceny wyrażeń+
i za*
pomocąeval(f(i)+a+f(i))
, w których operatora
jest umieszczony na stałe między wynikami rekurencyjnymi. Eval używa powiązańe=0,o=1
w opcjonalnych argumentach funkcji. Wyjście jest następnie pobierane mod 2.źródło
e+o
, więc potrzebuje zmiennych, aby odwoływały się do liczb.C, 79 bajtów
Prosta rekurencja. Opiera się na niektórych (przypadkowych?) Właściwościach bitowych czterech dozwolonych znaków wejściowych.
źródło
Narzędzia Shell + GNU, 33
Dane pobierane są z STDIN.
Robi to samo, odwracając dane wejściowe i oceniając je za pomocą kalkulatora opartego na stosie - w tym przypadku
dc
. Możemy zamieniće
i zao
pomocą0
i1
, ale wówczas trzeba będzie wstawić spacje, aby zapobiec zachłannemu przetwarzaniu cyfr na niepoprawne liczby.Zamiast tego
e
jest zastąpionyK
który jestdc
polecenie, aby przesunąć bieżącą dokładność na stosie, który domyślnie jest 0. Io
otrzymuje zO
którego jestdc
komenda do pchania aktualną bazę wyjściową do komina. To musi być nieparzyste, więc ustawiliśmy go na 15,Fo
zanim zrobimy cokolwiek innego w DC.Zatem wystarczy po prostu wziąć mod 2 i wydrukować
2%p
. Jedyne możliwe wartości to teraz0
i1
tak nie ma znaczenia, że baza wyjściowa jest 15. Następnietr
przekłada powrotem doo
lube
.Podoba mi się, jeśli zmrużysz oczy, to źródło prawie wygląda
dc Forever OK
.źródło
Poważnie , 24 bajty
Bardziej wydajne manipulowanie stosami może prawdopodobnie uczynić to krótszym, ale jestem zadowolony.
Pobiera dane wejściowe jako ciąg znaków, np
"+*oee"
Wypróbuj online (dane należy wprowadzić ręcznie)
Wyjaśnienie:
źródło
Rubin, 61 bajtów
Korzystanie z parsowania rekurencyjnego i algebry boolowskiej.
Funkcja odczytuje po jednym znaku ze standardowego wejścia. Jeśli czyta a
+
lub a*
, wywołuje się dwukrotnie, aby określić nieparzyste lub parzyste. Funkcja zwracatrue
dla nieparzystych ifalse
dlaeven
. Operatory^
XOR i&
AND służą do określenia „nieparzystości” odpowiednio wyrażeń dodawania i mnożenia.Oto wersja bez golfa:
Dzięki @Shel za wskazanie błędu w początkowej wersji.
źródło
+ee
dajeo
. Podoba mi się ten pomysłf^f
ze!f^f
if&f
zef|f
i to działa. Program do uruchamiania przypadków testowych: pastebin.com/ufXfd1vcf^f
if&f
odwróciłem$_==?e
i?e:?o
zamiast tego :)Minkolang 0,14 , 40 bajtów
Próbowałem wykonać sprytną metodę eval, ale okazuje się, że żadne wartości dodane do codbox poza pierwotną przestrzenią nigdy nie zostaną osiągnięte przez licznik programu. Więc zrobiłem mniej sprytną metodę ewaluacji. : P
Wypróbuj tutaj.
Wyjaśnienie
źródło
JavaScript,
110 10694 bajtyZ pewnością nie jest to najmniejsze rozwiązanie, ale prawdopodobnie najmniejsze możliwe rozwiązanie w pełnym języku, takim jak JavaScript!
źródło
?:
.while(i.length>2)i=i.replace(/[+*][eo]{2}/,function(o){return"+oe+eo*oo".indexOf(o)>=0?"o":"e"})
. Lub jeśli zmienisz funkcję grubej strzałki ECMAScript 6, towhile(i.length>2)i=i.replace(/[+*][eo]{2}/,o=>"+oe+eo*oo".indexOf(o)>=0?"o":"e")
. Ale niestety wymaganie mówi o programie lub funkcji, podczas gdy bieżący kod jest fragmentem kodu. Powinien obsługiwać dane wejściowe i wyjściowe lub argumenty i zwracane wartości.i
jak powiedziałeś.O ,
24201918 bajtówZajmuje wejście, odwraca go, przypisuje
e
do 2 io
do 1 istanowisk go do Tumblrocenia go jako kod wyjścia.Wyjaśnienie:
źródło
GNU Sed, 36
Po wysłaniu Widziałem to dokładnie takie samo podejście jak na Perl odpowiedź @ manatwork i @ randomra za Retina odpowiedź . Sądzę więc, że równie dobrze mogę pójść na całość i pożyczyć ich
\W\w\w
.Dzięki @Ruud za golenie 4 bajtów.
źródło
+
, tracisz 2 bajty za ucieczkę|
, ale końcowym rezultatem jest to, że wygrywasz 1 bajt za opcję upuszczenia-r
.|
potrzeby ucieczki, gdy-r
nie jest używany. Jeszcze 2 bajty więcej niż wynik - dzięki!Haskell, 160 bajtów
Zadzwoń
f
.źródło
JavaScript,
9271 bajtówJest to trochę zaciemnione, ale chciałem zrobić coś przy użyciu
eval
operatorów bitowych. Adnotacja:Powtarzanie
(e[…]>"e")
mnie trochę denerwuje, ale nie jest to również lepsze (103 bajty):W końcu podejście @ Arkain z prostym dopasowywaniem podciągów jest super. Utworzono funkcję z pewnymi optymalizacjami:
źródło
Dart, 173 bajtów
To nie jest konkurencyjne, ale cokolwiek. Istotą rozwiązania jest, począwszy od 0, rekurencyjne zastępowanie każdego operatora oceną pary znaków następujących po tym operatorze, a następnie usuwanie tych znaków z listy.
źródło
Haskell, 231 bajtów
Oto podejście przy użyciu poważnego języka;)
Wersja golfowa:
Przykład:
Niegolfowana i dość kompleksowa wersja:
Przykład:
Funkcje: Dopasowywanie wzorców i rekurencja.
źródło
Jolf, 11 bajtów
(Niekonkurencyjne, ponieważ język postdatuje pytanie.) Wypróbuj tutaj!
(Zamień
\x12
na rzeczywisty znak\x12
. Powinno to nastąpić automatycznie w tłumaczu.)Wyjaśnienie:
źródło
Python 3,
171145135 bajtówNie jestem konkurencyjny, ale dobrze się bawiłem, więc nie mogłem tego zatrzymać dla siebie. W przeciwieństwie do (bardzo sprytnego) wpisu Pythona w iteratorze rekurencyjnym z iteratorem feersum , ten odwraca dane wejściowe, a następnie wykonuje starą, opartą na stosie analizę składni odwrotnej polskiej notacji.
źródło
callable()
jest eleganckie, ale długie. (Odwrócenie warunku i usunięcienot
byłoby krótsze.) Zamiast tego sprawdź, czy m jest liczbą całkowitą,m in[0,1]
byłoby krótsze, ale sprawdzenie, czy c jest wartością,c in'eo'
byłoby jeszcze krótsze. To później jest takie samo jakc>'a'
w tym przypadku.for
:s+=[c>'e'if c>'a'else{'*':o.and_,'+':o.xor}[c](s.pop(),s.pop())]
s.pop()
(dwa razy) każdej pętli. Do tej pory nie zawracałem sobie głowy testowaniem; ale hej, punkt jest teraz dyskusyjny.operator
modułu?bool.__and__()
ibool.__xor__()
są bardziej poręczne:s+=[c>'e'if c>'a'else getattr(s.pop(),{'*':'__and__','+':'__xor__'}[c])(s.pop())]
. Ale na podstawie gnibbler „s końcówki krojenie , które mogą być zamienione nas+=[c>'e'if c>'a'else getattr(s.pop(),'__'+('axnodr'[c>'*'::2])+'__')(s.pop())]
.^
,&
) i ichoperator
odpowiedniki, zapominając o metodach, które faktycznie je implementują. Aha, areversed()
teraz został odrzucony dzięki kolejnej wskazówce golfowej Python .Haskell,
9894 bajtówPrzepraszam, że przeszkadzam w kolejnej próbie Haskella; chciałem tylko udowodnić, że jest to bardzo możliwe w mniej niż 100 bajtach.
Definiuje funkcję,
p
która przyjmuje dowolne prawidłowe wyrażenie jako parametr i zwraca wynik jako ciąg długości 1.Przykład:
Funkcja działa poprzez wielokrotne zmniejszanie najbardziej wysuniętego w prawo operatora w ciągu, aż nie pozostaną żadne operatory.
źródło
Dodaj ++ , 46 bajtów
Wypróbuj online!
Stopka po prostu wylicza wszystkie przykładowe dane wejściowe i odpowiadające im dane wyjściowe.
Jak to działa
Podobnie jak w przypadku utraty odpowiedzi tutaj, wykorzystuje to wymianę i ocenę. Naszym głównym zadaniem jest
f
, ag
jest funkcją pomocnika. Użyjemy"*e*o*e*oe"
(który jeste
) jako przykład.f
zaczyna się od pobrania ciągu wejściowego i odwrócenia go, ustępując"eo*e*o*e*"
. Następnie mapujemyg
każdy element:g
zaczyna się od zduplikowania argumentu, aby zachować kopię do ostatniego polecenia. Następnie sprawdzamy, czy argument znajduje się w ciągu"oe"
, dając 1 dla liter i 0 dla*
lub+
. Następnie ponownie wypychamy argument i sprawdzamy, czy jest on równy"e"
. Ten wynik jest następnie dodawany do poprzedniej kontroli. Daje to 0 do albo*
lub+
, 1 doo
i 2 oe
. Następnie bierzemy logiczne OR między tą wartością a argumentem. Jeśli wartość wynosi 0 , jest ona zastępowana argumentem (tj.*
Lub+
), w przeciwnym razie pozostawia się ją taką, jaka jest (tj. 1 i 2 ).Konwertuje wszystkie litery na odwrocie wejścia na wartość liczbową. Następnie łączymy każdy element spacjami, aby cyfry nie były konkatenowane. W naszym przykładzie daje to ciąg znaków
"2 1 * 2 * 1 * 2 *"
. Możemy to następnie ocenić za pomocą notacji Postfiksa Add ++, uzyskując 8 . Następnie bierzemy parzystość tej wartości, dając 0 dla liczb parzystych i 1 dla liczb nieparzystych, po czym indeksujemy do łańcucha"eo"
i zwracamy odpowiednią literę.źródło