To jest golf golfowy .
W tym wyzwaniu będziemy pisać programy / funkcje, które rozwiązują zagadki „ Rycerze i Łowcy ”.
tło
Znajdziesz się na wyspie ... itd. ... każda osoba na wyspie oprócz ciebie jest rycerzem lub łajdakiem .
Rycerze mogą składać tylko prawdziwe oświadczenia.
Łotr może składać tylko fałszywe oświadczenia.
Nie chcę rygorystycznie definiować „oświadczenia”, ale powiemy, że oświadczenie jest czymkolwiek, co jest albo „prawdziwe”, albo „fałszywe”. Zauważ, że wyklucza to zdania paradoksalne.
Na potrzeby tego wyzwania napotkasz grupy wyspiarzy; złożą ci oświadczenia.
Twoim zadaniem jest ustalenie, kto jest rycerzem, a kto łotrem.
Wejście:
Otrzymasz (w dowolnym rozsądnym formacie) następujące informacje:
Lista obecnych osób. Zostaną nazwane wielkimi literami „AZ”. Narzucony przez nie limit liczby osób nie zostanie przekroczony.
Oświadczenia, które składa każda osoba. Poniżej znajdują się ważne szczegóły na ten temat.
Wynik
Następnie wydrukujesz (w dowolnym rozsądnym formacie), czym jest każda osoba. Na przykład, jeśli byliby gracze A B C D
i A
był rycerzem, ale reszta to łajdaki, możesz wyjść
A: 1
B: 0
C: 0
D: 0
Ważne szczegóły:
Wielkie litery alfabetu AZ odnoszą się do wyspiarzy.
Znaki
0
(zero) i1
(jeden) odnoszą się odpowiednio do „Knave” i „Knight”. (Możesz dowolne dwa inne znaki inne niż AZ, o ile określisz)Każdy obecny wyspiarz może złożyć dowolną naturalną liczbę oświadczeń lub może nic nie mówić.
W instrukcjach można używać normalnych operatorów logicznych ( IS *, AND, OR, NOT ). Oprócz tego, praw de Morgana i warunkowe mogą być użyte. Poniżej znajdują się przykłady, w jaki sposób mogą być prezentowane w formie mówionej, a następnie w jaki sposób mogą być wprowadzane do twojego programu.
(* w bardziej technicznych uwagach. Operator „IS” jest naprawdę używany jako zabezpieczenie (co nie jest operatorem logicznym). Kiedy mówię „A jest rycerzem”, naprawdę mam na myśli, że „A jest członkiem zestawu Knights ". Prawdziwym operatorem byłby„ ϵ ”. Dla uproszczenia zamiast tego użyjemy„ = ”.)
Korzystam z następujących (możesz używać czegokolwiek, o ile jest to uzasadnione i spójne):
^
Iv
LUB=
JEST~
NIE=>
IMPLIKACJEX:
Osoba X twierdzi, że ...
Osoba Z może wykonać dowolną kombinację dowolnego z następujących rodzajów oświadczeń:
Osoba Z mówi, że ...
Osoba A jest rycerzem.
Z: A = 1
Osoba Q jest Łowcą.
Z: Q = 0
Jestem rycerzem.
Z: Z = 1
Osoba A jest rycerzem LUB Osoba B jest rycerzem.
Z: ( A = 1 ) v ( B = 1)
Osoba C jest rycerzem, a ja jestem Knave.
Z: ( C = 1 ) ^ ( Z = 0 )
Osoba R NIE jest rycerzem.
Z: ~( R = 1 )
Ponadto dane wejściowe mogą również wykorzystywać prawa De Morgana
NIE jest prawdą, że zarówno osoba A, jak i osoba B są Łotrami
Z: ~( ( A = 0 ) ^ ( B = 0 ) )
Fałszem jest, że osoba A lub osoba B jest rycerzem
Z: ~( ( A = 1 ) v ( B = 1) )
Wreszcie można zastosować warunki warunkowe i ich negacje
Jeśli jestem rycerzem, osoba B jest Knave
Z: ( Z = 1 ) => ( B = 0 )
NIE jest prawdą, że jeśli osoba B jest rycerzem, to osoba C jest podstępem.
Z: ~( ( B = 1 ) => ( C = 0 ) )
Uwagi na temat warunków warunkowych
Sprawdź wikipedię, aby uzyskać więcej informacji.
Instrukcja warunkowa przybiera postać p => q , gdzie p i q same są instrukcjami. p jest „poprzednikiem”, a q jest „konsekwencją”. Oto kilka przydatnych informacji
Negacja warunku wygląda następująco: ~ (p => q) jest równoważne p ^ ~ q
Fałszywa przesłanka implikuje wszystko. To znaczy: jeśli p jest fałszem, to dowolna instrukcja p => q jest prawdą, niezależnie od tego, czym jest q . Na przykład: „jeśli 2 + 2 = 5, to jestem Spiderman” to prawdziwe stwierdzenie.
Kilka prostych przypadków testowych
Przypadki te są podane w następujący sposób (1), w jaki sposób przedstawilibyśmy problem w mowie (2), w jaki sposób moglibyśmy przedstawić komputerowi (3) prawidłowe dane wyjściowe, które może dać komputer.
Osoba A i osoba B podchodzą do ciebie na drodze i składają następujące oświadczenia:
Odp .: B to łotr lub ja jestem rycerzem.
B: A jest rycerzem.
Odpowiedź:
B to Rycerz, a A to Rycerz.
Wejście:
A B # Cast of Characters
A: ( B = 0 ) v ( A = 1)
B: A = 1
Wynik:
A = 1 B = 1
Osoby A, B i F podchodzą do ciebie na drodze i składają następujące oświadczenia:
Odp .: Jeśli jestem rycerzem, B jest Knave.
B: Jeśli to prawda, to F też jest Knave.
Odpowiedź:
A to Rycerz, B to Knave, F to Rycerz.
Wejście
A B F
A: ( A = 1 ) => ( B = 0 )
B: ( A = 1 ) => ( F = 0 )
Wynik:
A = 1 B = 0 F = 1
Q, X i W podchodzą do ciebie na drodze i składają następujące oświadczenia:
W: To nieprawda, że zarówno Q, jak i X są Rycerzami.
P: To prawda.
X: Jeśli to, co mówi W, jest prawdą, to co mówi Q, jest fałszywe.
Odpowiedź:
W i Q są Rycerzami. X to Łotr.
Wejście
Q X W
W: ~( ( Q = 1 ) ^ ( X = 1 ) )
Q: W = 1
X: ( W = 1 ) => ( Q = 0 )
Wynik
W = 1 Q = 1 X = 0
Istnieje podobne wyzwanie sprzed 3 lat, które koncentruje się na analizie składni i nie zawiera warunkowych ani De Morgana. A zatem, jak twierdzę, jest wystarczająco różny pod względem ukierunkowania i wdrożenia, aby uniknąć tego problemu.
To wyzwanie zostało na krótko zakończone jako oszustwo. Od tego czasu został ponownie otwarty.
Twierdzę, że to wyzwanie jest przede wszystkim inne. Drugie wyzwanie koncentruje się na analizie angielskiego, ale tak nie jest. Po drugie, używa tylko AND i OR, podczas gdy używa to warunkowe i pozwala na rozwiązywanie wielu innych zagadek. Ostatecznie pytanie brzmi: czy odpowiedzi na to wyzwanie można w prosty sposób zastąpić tym, i uważam, że włączenie warunków warunkowych i negacji warunkowych zapewnia wystarczającą złożoność, że należy wprowadzić bardziej zdecydowane zmiany, aby aby sprostać temu wyzwaniu.
(B=1)=>(C=0)
?~((B=1)=>(C=0))
czy(B=1)=>(C=1)
coś innego?OR
, może to byćA:1 B:1
lubA:1 B:0
ponieważ BB=1
może być fałszywe, podczas gdy A nadal będzie prawdą.(B=1)^(C=1)
tak jak w przypadku normalnych warunków warunkowychOdpowiedzi:
Python 3,
450342307 bajtówEdycja: okazuje się, że zapomniałem importu ...
Moje pierwsze rozwiązanie wykorzystuje elastyczne nazewnictwo zapytań
Możesz zadzwonić do powyższego za pomocą
Następny tutaj używa tego samego formatu zapytań, co widziany w PO, nie ma też niektórych modyfikacji, które wprowadziłem w pierwszym. Ma 417 bajtów, ponieważ konwertuje między dwoma formatami.
Można to nazwać:
Oboje wracają
Niegolfowane Objaśnienie:
Drugie rozwiązanie wymaga również 3.5 (nie 3.4) ze względu na użycie PEP 448
źródło
Mathematica, 80 bajtów
Wyjaśnienie
Funkcja
F
przyjmuje dwa argumenty,c
jest listą imion wszystkich postaci,s
to lista instrukcji, z których każda zawiera dwie części - kto co mówi.Na przykład są trzy znaki, Q, X i W.
I mówią:
gdzie
True
iFalse
oznacza odpowiednio Rycerzy i Łotrów. Następnieda
{{q->True, x->False, w->True}}
, co oznacza, że istnieje tylko jedno rozwiązanie, w którym Q i W są Rycerzami, podczas gdy X jest Knave. Jeśli istnieje więcej niż jedno rozwiązanie, wynik będzie wyglądał{{...},{...},...}
Algorytm jest bardzo prosty.
{True,False}~Tuples~Length@c
daje wszystkie możliwe kombinacje Rycerzy i Łotrów pomiędzy postaciami. NastępnieThread[c->#]&/@
zbuduj tablicę reguł na podstawie tych kombinacji. W przypadku dwóch znaków A i B tablica będzieZastępując instrukcje jednym wierszem tych reguł, otrzymamy tablicę wyglądającą
Pierwsza kolumna tej tablicy to tożsamości mówców, a druga kolumna wskazuje, czy ich stwierdzenia są prawdziwe, czy fałszywe. Prawidłowe rozwiązanie wymaga zgodności między tożsamościami mówców a ich oświadczeniami. Powyższa tablica oznacza, że ta kombinacja nie jest rozwiązaniem, ponieważ drugi mówca, rycerz, składa niepoprawne stwierdzenie.
dokonuje podstawień i wybiera te kombinacje, które spełniają warunek.
źródło
Ruby, 128
Jest to ten sam algorytm, co wszyscy, wypróbuj wszystkie możliwe kombinacje noże i rycerzy i zobacz, które laski. Mam inny, nad którym pracuję, ale myślę, że będzie on dłuższy (choć bardziej interesujący).
Dane wejściowe instrukcji muszą być:
&
I|
LUB==
JEST!
NIE>
IMPLIKACJEX:
Osoba X twierdzi, że ...Wymagam także, aby każda instrukcja i pod-instrukcja były w nawiasach. Jedynym problemem związanym z tą wersją jest to, że przechodzi ona co najwyżej 2 ^ 26 iteracji, a jeśli nie wszystkie są łotrami, co najmniej 2 ^ (26-n) iteracji ! Mówiąc z perspektywy, oznacza to, że jeśli są dwie osoby, a przynajmniej jedna nie jest łotrem, zajmie to co najmniej 16 777 216 iteracji !
Aby to ograniczyć, przesyłam następujące w 168 bajtów. Sub
26
do#{o.size}
wyciąć go z powrotem do 161.Ale jeśli zamiast tego mogę użyć tablicy osób i mapy instrukcji, np .:
Potem zmniejszam do 128.
źródło