Znajdź wynik gry wojennej
Kiedy byłem w szkole podstawowej, była gra „Rock-Paper-Scissors”, w którą graliśmy podczas zgromadzeń, czekając na nauczyciela, w przerwie itp. Nazwaliśmy to „Wojną”. Jednak po kilku poszukiwaniach okazuje się, że jest to znacznie prostsza odmiana „Strzelby” (według WikiHow) . Nazywam to „Wojną”, ponieważ zasady są nieco inne:
2 osoby siedzą naprzeciwko siebie. Celem gry jest „zabicie” drugiego gracza. W każdej turze możesz wykonać jeden z 3 ruchów:
Przeładuj : masz broń, która trzyma pojedynczy strzał. Musi zostać przeładowany, zanim będzie można go wystrzelić za każdym razem. Przeładowywanie, gdy masz już amunicję, jest legalne, ale nic nie robi. Przeładowanie zostało symbolizowane przez stuknięcie świątyń obiema rękami. Każdy gracz zaczyna od 0 amunicji.
Strażnik : jedyny bezpieczny ruch. Jeśli zostaniesz postrzelony podczas obrony, nie umrzesz. Ochrona symbolizowana była przez skrzyżowanie rąk nad klatką piersiową.
Ogień : wystrzel swoją broń. Aby skutecznie strzelać, musisz przeładować od ostatniego strzału. Jeśli twój przeciwnik przeładowuje, wygrywasz. Jeśli oni również strzelają, a oboje macie amunicję, jest to remis. Jeśli pilnują, zmarnowałeś amunicję. Podczas gdy strzelanie bez amunicji jest legalnym posunięciem, nic nie robi i pozostawia cię bezbronnym jak przeładowanie. Strzelanie było symbolizowane przez wskazanie na drugiego gracza.
Rozgrywano go podobnie do RPS, ponieważ każdy gracz jednocześnie odrzuca swój wybór (dwukrotnie stukaliśmy nogami między turami, aby zachować rytm, ale to nie jest ważne dla wyzwania).
Wyzwanie:
Twoim zadaniem jest znalezienie wyniku gry wojennej. Może to być funkcja lub pełny program.
Wejście
Opcja wybrana przez każdego gracza w każdej turze będzie reprezentowana przez postać / ciąg znaków:
r : przeładuj
g : strażnik
f : ogień
Dane wejściowe będą listą par, ciągiem rozdzielanym / nieosiąganym, lub cokolwiek innego wzdłuż tych linii.
Przykładowym wejściem w Pythonie może być [("r", "g"), ("f", "r")]
, co oznacza, że w pierwszej turze pierwszy gracz zostanie przeładowany, a drugi gracz będzie strzeżony. W drugiej turze pierwszy gracz strzela, a drugi gracz przeładowuje. Gracz pierwszy wygrywa tę grę. Te same dane wejściowe mogą być ewentualnie reprezentowane "r g f r"
, "rgfr"
, "rg fr"
"rg-fr"
...
Możesz założyć, co następuje:
Dane wejściowe będą pasować do wybranego przez Ciebie formatu i będą zawierać tylko prawidłowe znaki.
Ktoś umrze w ciągu 100 tur.
Nie możesz jednak założyć, że tury kończą się, gdy ktoś umrze.
Wynik
Wartość wskazująca, kto wygrał (lub kto wygrał jako pierwszy *
). Możesz wybrać dane wyjściowe dla każdego scenariusza, ale musisz uwzględnić następujące kwestie:
Gracz 1 wygrywa
Gracz 2 wygrywa
Zabijają się nawzajem (remis)
Każdy wynik musi mieć wartość dzielnicową i zawsze musi być taki sam dla każdego scenariusza.
Na przykład: możesz wypisywać, 1
gdy gracz 1 wygrywa, 2
gdy gracz 2 wygrywa, aw 0
przypadku remisu. Musisz wtedy zawsze generować, 1
gdy gracz 1 wygra, 2
gdy gracz 2 wygra, a także 0
w przypadku remisu.
Można go zwrócić lub wydrukować na standardowe wyjście. Końcowe białe znaki są w porządku.
Żeby było jasne, jedynym scenariuszem prowadzącym do losowania jest sytuacja, gdy obaj gracze strzelają i obaj mają amunicję.
*
Ponieważ w tym wyzwaniu tury mogą być kontynuowane po śmierci kogoś, możliwe, że więcej niż jeden gracz może wygrać. Musisz dowiedzieć się, kto wygrał jako pierwszy, zgodnie z danymi wejściowymi.
Przypadki testowe (zakładając, 1
kiedy wygrywa P1, 2
kiedy wygrywa P2 i 0
remis):
"rg fr" => 1 (P1 shot P2 while they were reloading)
"rg ff" => 1 (They both shot, but only P1 had ammo)
"rr ff" => 0 (Both had ammo and shot each other)
"rr ff rr fg" => 0 (Both had ammo and shot each other. Everything after the first win is ignored)
"rr fg rf" => 2 (P2 shot P1 while they were reloading)
"rf gg rr fg rr fr" => 1
(P2 tried to shoot but didn't have any ammo, then they both guarded, then they both reloaded, then P2 blocked a shot, then they both reloaded again [but P2 still only has 1 ammo!], then P1 shoots P2 while they're reloading.
"rr gf fr rf gg rg ff" => 1
^ Player 1 wins here. The rest to the right has no effect on the output
To jest golf golfowy, więc wygrywa najmniejsza liczba bajtów!
Uwaga: jak pokazują przypadki testowe, musisz obsługiwać „głupie” ruchy. Jest całkowicie uzasadnione, że gracz próbuje strzelać, gdy nie ma amunicji lub przeładowuje 2 tury z rzędu (i gromadzi tylko jedną amunicję).
{"rff","rgf"}
?Odpowiedzi:
Siatkówka , 36 bajtów
Format wejściowy powinien być parami oddzielonymi od linii, np
Wyjście to
!_
wygrywa gracz 1,_!
jeśli gracz 2 wygrywa i!!
jeśli jest remis.Wypróbuj online! (Zestaw testowy, który dla wygody wykorzystuje separację przestrzeni).
Musiałem całkowicie przeoczyć to wyzwanie. Jestem pewien, że inaczej spróbowałbym tego wcześniej w Retinie. :)
Wyjaśnienie
Zaczniemy od oznaczenie „valid” strzałów obracając pierwszy
f
po każdymr
INTO!
. Robimy to poprzez dopasowanie każdegof
z nich, z którego można znaleźć jednegor
gracza bez przechodzenia przez innegof
. Ograniczenie wyszukiwania dor
tego samego gracza jest łatwe, zawsze idąc po trzy postacie na raz.Teraz odrzucamy wszystkie tury, w których ktoś się strzegł, ponieważ tura końcowa nie może być jedną z nich.
Teraz trzymamy tylko pierwszą turę, która zawiera
!
. Jeśli zdarzy się ważny strzał (i wiemy, że nikt nie pilnował), gra się kończy.Na koniec musimy skonsolidować ciąg, aby uzyskać spójne wyniki, i po prostu robimy to, zamieniając
!
znaki niebędące znakami (albor
albof
) w_
.źródło
Python, 139 bajtów
Pobiera dane wejściowe na stdin w postaci listy 2-znakowych ciągów znaków (np. [„Rf”, „rr”, „rg”, „ff”]). Wykazuje 1, jeśli gracz 1 wygra, -1, jeśli gracz 2 wygra, i 0 w przypadku remisu.
Wyjaśnienie: Najpierw sprawdza, czy ktoś wystrzelił pocisk, jeśli tak, gra się kończy. Następnie ustalamy, czy gracze przeładowali broń lub zmarnowali amunicję.
To jest mój pierwszy post codegolf :)
źródło
JavaScript (ES6),
10810793918985 bajtówZa pomocą Tytusa zapisano 4 bajty
Pobiera dane wejściowe jako tablicę 2-znakowych ciągów opisujących ruchy odtwarzane przez każdego gracza.
Zwroty:
1
jeśli gracz 1 wygra2
jeśli gracz 2 wygra3
na remisJak to działa
Utrzymujemy maskę bitów
b
opisującą, kto ma załadowaną kulę:Używamy sekwencji De Bruijn
'ffrfgrrggf'
do zidentyfikowania wszystkich 9 możliwych kombinacji ruchów. Używamy masek bitowych OR i AND do aktualizacjib
zgodnie z kombinacją przenoszenia. Dob
ustalenia zwycięzcy używamy trzeciego zestawu masek bitowych, które są AND'owanew
. (Tylko trzy zwycięskie kombinacje sąff
,fr
arf
.)Warto zauważyć, że maski OR i AND można przechowywać z tym samym wzorem, przesuniętym o dwie pozycje.
Przypadki testowe
Pokaż fragment kodu
źródło
0
(nikt nie został zastrzelony) lub3
(gracze się zabijają) w przypadku remisu. Nie jestem pewien, czy jest to dozwolone. Jeśli nie, mogęw%3
zamiast tego wrócić .&
Maska może wynosić 0fr,rf,ff
.'312'['0210231'[m='ffrfgrrggf'.search(c)]|'233331'[m-3]&b]
lub'123'['2100231'[m='frffgrrggf'.search(c)]|'233331'[m-3]&b]
zapisz jeden bajt; ale czy one działają?["rr","fg","fr","rf"]
&
ma wyższy priorytet niż|
, więc zmiana kolejności nie powinna niczego tam zmieniać (oprócz zapisywania bajtu). Ale w moim kodzie brakowało tego zadania. Spróbować...'123'[b='2100231'...
.Perl 6 ,
7162 bajtówRozwiązanie oparte na regeksie.
Pobiera dane wejściowe jako ciąg znaków w formularzu
"rg fr"
.Trzy możliwe wyniki są wartościami wyliczeniowe
More
(odtwarzacz 1 wygranych)Less
(odtwarzacz 2 wygranych)Same
(draw) - przez co zmienią się w tych słowach podczas drukowania, albo w1
,-1
,0
gdy przekonwertowany numerów.Wypróbuj online!
Jak to działa
Wykonuje dwa dopasowania wyrażeń regularnych na wejściu. Po interpolacji dwa wyrażenia regularne to:
r[..[r|g]]*.[r|f]f
- Pasuje do pierwszego udanego strzału przez gracza 2.r[..[r|g]]*..f[r|f]
- Pasuje do pierwszego udanego strzału przez gracza 1.W każdym przypadku zwraca pozycję końcową match (
.to
) lub nieskończoność, jeśli nie było dopasowania.Stosuje
<=>
operatora do dwóch pasujących pozycji końcowych. Zwraca wartość zOrder
wyliczenia (More
,Less
lubSame
), w zależności od tego, czy pierwszy argument jest większy, mniejszy czy równy drugiemu.źródło
some number
? I czy rzeczywiście używasz takich znaków we wspólnym kodzie Perla, czy to tylko do gry w golfa?[Menu] i n f
(nazywa się to sekwencją tworzenia ). Jednak wszystkie symbole Perla 6 mają wersje ASCII - np.Inf
I∞
są synonimami - więc nie trzeba używać symboli Unicode w kodzie Perla 6. Po prostu mi się podoba ... :)Haskell ,
101 9187 bajtówWypróbuj online! Funkcja infix
#
przyjmuje dwa ciągi znaków reprezentujące działania każdego z dwóch graczy i zwraca,(0,1)
jeśli gracz 1 wygra,(1,0)
dla gracza 2 i(0,0)
remisu.Przykładowe użycie:
Wyjaśnienie:
Funkcja infix
!
tłumaczy sekwencję akcji'r'
(przeładowanie),'f'
(ogień) i'g'
(straż) na sekwencję obserwowalnych akcji0
(rzeczywisty ogień),1
(brak akcji) i2
(strażnik), gdzie akcja ogniowa jest liczona tylko jako faktyczna akcja ogniowa jeśli pocisk jest załadowany i jako brak działania w przeciwnym razie. Aby to osiągnąć, pierwszym argumentemn
jest to,0
czy pocisk jest załadowany i1
czy pistolet nie jest załadowany. W ten sposób każdy'f'
można po prostu zastąpić prądemn
. (n=0
-> załadowany -> rzeczywisty pożar ->0
,n=1
-> rozładowany -> brak akcji ->1
)Zatem powstaje dziewięć możliwości
(0,0)
: Obaj gracze strzelają i giną, gra się kończy.(0,1)
lub(1,0)
: Jeden gracz strzela do drugiego, gra się kończy.(0,2)
lub(2,0)
: Jeden gracz strzela, ale drugi chroni, gra jest kontynuowana.(1,1)
,(1,2)
,(2,1)
Lub(2,2)
: Brak pędy graczy, gra toczy się dalej.Z założenia suma opcji zakończenia gry jest mniejsza niż 2, a suma każdej możliwej kontynuacji gry jest większa lub równa 2. Wynik gry jest wtedy pierwszą krotką z sumą mniejszą niż 2.
źródło
Partia, 249 bajtów
Dane wejściowe mają postać par znaków dla każdej tury i wyników według poziomu błędu (0 = remis, 1 = gracz 1, 2 = gracz 2).
x
iy
sprawdzaj, czy gracz ma amunicję, więc kiedy oba wystrzelą, wynik jest3-x-x-y
, chyba że to 3, w takim przypadku kontynuujemy. W linii 5 nadużywam parsera Batcha -%1
(który jest bieżącym posunięciem) jest zastępowany przed wykonaniemshift
instrukcji i usunięciem, więc nadal przechodzimy do właściwej etykiety.źródło
Clojure, 168 bajtów
Mniej gra w golfa (jeśli obie osoby żyją,
M
aktualizujemy amunicję i stan życia wroga, w przeciwnym razie przywracamy aktualny stan):Przykładowe użycie (pierwszy element informuje, czy Gracz 1 żyje pod koniec gry, drugi element informuje, czy Gracz 2 żyje, trzeci i czwarty informują o stanie amunicji, co nie ma znaczenia przy ustalaniu zwycięzcy):
Aktualizacja: Cóż, spójrz na to,
loop
ma identyczną długość! Uważam, żereduce
wersja jest łatwiejsza do opracowania, ponieważ można łatwo sprawdzić stany pośredniereductions
.źródło
[l1 l2 r1 r2]
(jego zmodyfikowane wartościlet
i oryginalne wartości) i tefn
podpisy.loop
. Uważam, że prowadzi to do czystszego kodu. Gdy tylko muszę złożyć z więcej niż 1 akumulatorem, przełączam się.PHP,
10710190 bajtówza pomocą maski bitowej $ d dla statusu ładowania i sekwencji DeBruijn dla ruchów strzelania.
przyjmuje dane wejściowe jako 2-znakowe argumenty wiersza poleceń, uruchamiane z
-nr
.awaria
fr
position = 1 = P1 strzela;rf
= pozycja 2 = ogień P2,ff
= pozycja 3 = ogień obag<$m
<=>f<$m[0]
(f<$m
zawsze jest to prawda, ponieważ istnieje drugi znak).źródło
Python, 200 bajtów
źródło
turns
zamiast zamiastt
, co oznacza, że program jest znacznie większy niż to konieczne. Proszę również rozpocząć przesyłanie od czegoś takiego#Python 2, 200 bytes
(zakładając, że jest to 2, a program ma 200 bajtów długości), więc używany język jest jasny.Clojure,
180173 bajtów-7 bajtów, zmieniając funkcję na pełną zamiast zamiast makra. To pozwala mi tworzyć makra funkcji wewnętrznych, co trochę oszczędza.
To bardzo dosłowne rozwiązanie. Jestem trochę zatroskany, ponieważ właśnie napisałem pełną wersję gry, i jest to zasadniczo bardzo uproszczona wersja algorytmu, którego użyłem. Prawdopodobnie jest wiele optymalizacji, które mogę wykonać, ale jestem z tego całkiem zadowolony. Wyjaśnienia znajdują się w kodzie wstępnie golfowym.
źródło