Zdobądź papier-kamień-nożyce

70

Biorąc pod uwagę dwa ciągi znaków „Rock”, „Paper” lub „Scissors”, określ wynik rundy RPS . Wyjście 1, jeśli pierwszy gracz wygra, -1, jeśli drugi gracz wygra, lub 0, jeśli remis.

Rock Rock -> 0
Rock Paper -> -1
Rock Scissors -> 1
Paper Rock -> 1
Paper Paper -> 0
Paper Scissors -> -1
Scissors Rock -> -1
Scissors Paper -> 1
Scissors Scissors -> 0

Musisz użyć dokładnych łańcuchów „Rock”, „Paper” i „Scissors” jako danych wejściowych. Możesz wybrać, czy wybór pierwszego gracza będzie (konsekwentnie) podawany jako pierwszy czy drugi. Możesz je też traktować jako pojedyncze wejście z pojedynczym znakiem lub pustym separatorem. Dane wejściowe są gwarantowane w jednym z 9 możliwych par trzech opcji w formacie wejściowym.

Dane wyjściowe powinny mieć liczbę 1, 0 lub -1 lub reprezentację ciągu. Pływaki są w porządku. Więc są +1, +0,i -0.

Powiązane: Kodowanie gry RPS


Tabela liderów:

xnor
źródło
Czy pojedyncze wejście z pustym separatorem oznacza na przykład „papier skalny”?
Emigna
1
@Emigna Tak, ale wielkie litery jak RockPaper.
xnor
15
To BYŁO o wiele więcej zabawy, niż się spodziewałem, mój panie, są na to fajne sposoby.
Magic Octopus Urn
Czy dane wejściowe mogą być tablicą dwóch ciągów?
Luis Mendo,
@LuisMendo Tak.
xnor

Odpowiedzi:

73

Groovy, 67 56 50 bajtów

{a,b->Math.sin(1.3*((int)b[0]-(int)a[0])).round()}

Wypróbuj online!

Okazuje się, że gra w kamień, papier, nożyczki ma całkiem fajną właściwość.
Biorąc pod uwagę ciągi a i b, weź pierwszą literę każdego z nich, to daje dwa z następujących:R,P,S

Wyczerpująca lista możliwych wartości to (Po połączeniu 2 wyborów):

XX=ASCII=Y=Wanted output
RR=82-82=0=0
PP=80-80=0=0
SS=83-83=0=0
RS=82-83=-1=1
RP=82-80=2=-1
PS=80-83=-3=-1
PR=80-82=-2=1
SR=83-82=1=-1
SP=83-80=3=1

Reorganizacja listy w celu:

-3->-1
-2->1
-1->1
0->0
1->-1
2->-1
3->1

Daje nam sekwencję, która wygląda odwrotnie sinusoidalnie, i możesz faktycznie przedstawić tę formułę jako przybliżoną (a przez około mam na myśli zaledwie tyle, że wystarczy pracować, możesz uzyskać równanie, które jest martwe, ale kosztuje więcej bajtów):

-sin((4*a[0]-b[0])/PI).roundNearest() = sin(1.3*(b[0]-a[0])).roundNearest()

Uproszczenie 4 / pi do 1.3 zostało najpierw zasugerowane przez @flawr, a następnie przetestowane przez @titus dla całkowitej oszczędności 6 bajtów.

Wyjaśnienie równania

Dzięki podwójnym właściwościom zaokrąglania Groovy daje to prawidłową moc wyjściową dla papierowych nożyczek.


05AB1E , 10 bajtów (nie konkurować)

Ç¥13T/*.½ò

Wypróbuj online!

Tę samą odpowiedź przeniesiono do 05AB1E za pomocą nowych poleceń dodanych 26.10.2017.

Urna Magicznej Ośmiornicy
źródło
3
Nie można zrobić to za pomocą krótszy że -sin(x) = sin(-x)oznacza to, że po prostu odwrócenie kolejności ai bi upuszczanie wiodącym -? Poza tym wystarczające może być ustalenie przybliżenia 4/Pipodobnego 1.273, lub 1.3lub 9/7lub 5/4.
flawr
2
PS: Sugeruję również utworzenie linku, aby wypróbować go online, aby osoby takie jak ja mogły bawić się z twoim zgłoszeniem =)
flawr
3
Możesz zapisać 1 bajt sin(b-a)zamiast -sin(a-b). Świetne znalezisko!
Tytus
2
Zaoszczędź kolejne 7 bajtów, mnożąc przez 1.3zamiast 4/Math.PI; to wystarczająco dokładne.
Tytus
1
@carusocomputingXX=ASCII=Y=Wanted output RR=82-82=0=0 PP=83-83=0=0 SS=80-80=0=0
CraigR8806
44

C, 50 35 bajtów

#define f(i)*(short*)(i+7)%51%4%3-1

Zadzwoń fz ciągiem zawierającym obu graczy, bez separatora, a zwróci, czy pierwszy wygra.

Wyjaśnienie:

Patrząc na dziewięć możliwych ciągów, okazuje się, że pary liter w kolumnach 7 i 8 są unikalne:

       vv
RockPaper
PaperScissors
ScissorsRock
RockRock         // Sneakily taking advantage of the terminating zero
PaperPaper
ScissorsScissors
RockScissors
PaperRock
ScissorsPaper
       ^^

Przesunięcie przesunięte i dzikie, aby short*pobrać te pary liter i zinterpretować je jako liczby:

29285
29545
21107
107
25968
21363
29555
27491
20595

Wtedy chodziło o brute-force, aby znaleźć 51i 4pozostałości, które dotyczyło kolejno zmniejszających te numery do:

3 0 0 1 1 1 2 2 2

Który jest po prostu idealny, aby sfinalizować jeszcze jedną resztę na końcu i zrównoważyć wynik.

Zobacz na żywo na Coliru

Quentin
źródło
Po prostu nie rób niczego, jak obliczanie, -f(i)aby obliczyć wynik drugiego gracza - spowoduje nieoczekiwany wynik!
nneonneo
4
@nneonneo -(f(i))powinno działać dobrze. Makra są fajne!
nwp 12.01.17
18

MATLAB / Octave , 63 54 52 bajty

Jest to bardzo wygodne, że kody ASCII pierwszych liter Rock,Paper,ScissorsR=82,P=80,S=83. Jeśli odejmiemy 79, otrzymamy wygodnie 3,1,4, który wykorzystamy teraz jako indeksy macierzy: tutaj macierz 4x4 jest zakodowana na stałe, gdzie i,j-ty wpis odpowiada wynikowi, jeśli podłączysz wartości sprzed:

     1   2   3   4
  +---------------
1 |  0   0   1  -1
2 |  0   0   0   0
3 | -1   0   0   1
4 |  1   0  -1   0
A(5,5)=0;A(4:7:18)=1;A=A-A';@(x,y)A(x(1)-79,y(1)-79)

Wypróbuj online!

wada
źródło
16

Pure Bash, 31

Wzór na pożyczkę @ Dennisa :

a=$1$1$2
echo $[(${#a}^67)%3-1]

Wypróbuj online .


Poprzednia odpowiedź:

Pure Bash, 43 35

echo $[(7+(${#2}^3)-(${#1}^3))%3-1]
  • Uzyskać długość ciągu każdego Arg ( 4, 5, 8odpowiednio dla Rock, Paper, Scissors)
  • XOR każdy z 3 otrzymując 7, 6, 11(które wzięte mod 3. tego 1, 0, 2)

  • Następnie odejmij i baw się modem 3, aby uzyskać pożądany wynik.

Wypróbuj online .

Cyfrowa trauma
źródło
15

Python , 40 30 bajtów

lambda x,y:(len(2*x+y)^67)%3-1

Wypróbuj online!

tło

Zacząłem od szablonu funkcji

lambda x,y:(len(a*x+b*y)^c)%d-e

i przeprowadził wyszukiwanie siły z użyciem odpowiednich parametrów za pomocą następującego programu, a następnie wybrał jeden z implementacją o minimalnej długości.

RPS = 'Rock Paper Scissors'.split()
g = lambda x,y:2-(94>>len(6*x+y)%7)%4
r = range(1,10)
R = range(100)

def f(a, b, c, d, e):
    h = lambda x,y:(len(a*x+b*y)^c)%d-e
    return all(g(x, y) == h(x, y) for x in RPS for y in RPS)

[
    print('%2d ' * 5 % (a, b, c, d, e))
    for e in r
    for d in r
    for c in R
    for b in r
    for a in r
    if f(a, b, c, d, e)
]

Wypróbuj online!

Dennis
źródło
14

Mathematica, 32 bajty

Mod[{1,-1}.(Length/@#-3)!,3,-1]&

Nienazwana funkcja przyjmująca uporządkowaną parę list znaków, takich jak {{"R","o","c","k"},{"P","a","p","e","r"}}i zwracająca -1|0|1.

Chciałem, aby kod unikał nie tylko trzech słów wejściowych, ale także zbyt długiej nazwy funkcji ToCharacterCode; więc 4,5,8zamiast tego pracowałem z długością słów wejściowych i szukałem krótkiej funkcji tych długości, które dały odmienne odpowiedzi modulo 3. (Dzielenie całkowite przez 2 jest matematycznie obiecujące, ale te funkcje mają zbyt długie nazwy w Mathematica).

Okazuje się, że biorąc silnię (długość - 3) daje odpowiedzi 1,2,120, które są 1,-1,0modulo 3. Następnie po prostu obliczamy, modulo 3, różnicę dwóch wartości (poprzez iloczyn iloczynu {1,-1}.{x,y} = x-y, co jest dobrym sposobem, gdy dwie wartości znajdują się na liście).

Greg Martin
źródło
1
„Okazuje się ...” Masz na to oko
ngenisis
12

Rubin, 36 35 30 bajtów

a=->a,b{(a+b)[12]?a<=>b:b<=>a}

Wypróbuj na ideone.com

Wyjście testowe:

a=->a,b{(a+b)[12]?a<=>b:b<=>a}

puts a.call("Rock", "Rock")
puts a.call("Rock", "Paper")
puts a.call("Rock", "Scissors")
puts a.call("Paper", "Rock")
puts a.call("Paper", "Paper")
puts a.call("Paper", "Scissors")
puts a.call("Scissors", "Rock")
puts a.call("Scissors", "Paper")
puts a.call("Scissors", "Scissors")

0
-1
1
1
0
-1
-1
1
0

Wykorzystuje fakt, że 7 z 9 poprawnych wyników jest generowanych po prostu przez porównanie leksykograficzne z wykorzystaniem operatora statku kosmicznego <=>. Po (a+b)[12]prostu odwraca dane wejściowe do porównania, jeśli dane wejściowe są Paperi Scissors(a także Scissors Scissors- ale to w 0drugą stronę).

Dzięki Horváthowi Dávidowi za uratowanie mi postaci i GB za uratowanie mi kolejnej 5.

Gareth
źródło
Możesz użyć anonimowej lambdy i uratować 2 znaki.
GB
@GB Jeśli nie nadam tej funkcji nazwy, jak mam ją nazwać? To mnie oszukuje. Ale dziękuję za drugą wskazówkę - spojrzałem na to, ale odrzuciłem ją, ponieważ ScissorsScissors ma 16 lat, ale widzę, że to nie ma znaczenia. :-)
Gareth,
@Dennis Nie możesz zadzwonić bez przypisania. Czuję się jak oszustwo i niesprawiedliwe w stosunku do języków bez anonimowych funkcji, które muszą zdefiniować imię.
Gareth,
Oczywiście że możesz. tio.run/nexus/…
Dennis
10

Python , 39 36 34 33 bajtów

lambda x,y:2-(94>>len(6*x+y)%7)%4

Wypróbuj online!

Jak to działa

Rzućmy okiem na kilka wartości długości sześciu kopii xi jednej kopii y modulo 7 .

                                l(x,y) =:
x        y        len(x) len(y) len(6*x+y)%7
--------------------------------------------
Rock     Rock          4      4            0
Rock     Paper         4      5            1
Rock     Scissors      4      8            4
Paper    Rock          5      4            6
Paper    Paper         5      5            0
Paper    Scissors      5      8            3
Scissors Rock          8      4            3
Scissors Paper         8      5            4
Scissors Scissors      8      8            0

Możemy zakodować wyniki ( {-1, 0, 1} ), mapując je na zbiór {0, 1, 2, 3} . Na przykład odwzorowanie t ↦ 2 - t osiąga to i jest własną odwrotnością.

Oznaczmy wyniku X i Y o o (x, y) . Następnie:

x        y        l(x,y) o(x,y) 2-o(x,y) (2-o(x,y))<<l(x,y)
-----------------------------------------------------------
Rock     Rock          0      0        2                10₂
Rock     Paper         1     -1        3               110₂
Rock     Scissors      4      1        1            010000₂
Paper    Rock          6      1        1          01000000₂
Paper    Paper         0      0        2                10₂
Paper    Scissors      3     -1        3             11000₂
Scissors Rock          3     -1        3             11000₂
Scissors Paper         4      1        1            010000₂
Scissors Scissors      0      0        2                10₂

Na szczęście wszystkie bity w ostatnich kolumnach zgadzają się ze sobą, więc możemy LUB LUB utworzyć jedną liczbę całkowitą n i pobrać o (x, y) jako 2 - ((n ≫ o (x, y))% 4) . Wartość n wynosi 94 .

Dennis
źródło
9

Siatkówka , 35 31 bajtów

G`k P|r S|s R
*\)`.+
-
D`\w+
 .

Wypróbuj online!

Wyjaśnienie

Działa to w dwóch etapach. Najpierw drukujemy znaki minus dla odpowiednich danych wejściowych. Następnie drukujemy 0krawaty i 1inne.

G`k P|r S|s R
*\)`.+
-

To są dwa etapy. W )drugim etapie grupuje je razem, co *czyni je suchym przebiegiem (co oznacza, że ​​łańcuch wejściowy zostanie przywrócony po przetworzeniu, ale wynik zostanie wydrukowany) i \wstrzymuje drukowanie końcowego podawania linii. Dwa etapy razem wydrukują, -jeśli dotyczy.

Pierwszym etapem jest Getap rep który tylko trzyma linię, jeśli zawiera ona albo k P, r Salbo s R. Odpowiadają one przypadkom, w których musimy generować dane wyjściowe -1. Jeśli nie jest to jeden z tych przypadków, dane wejściowe zostaną zastąpione pustym ciągiem.

Drugi etap zastępuje .+(cały ciąg, ale tylko jeśli zawiera co najmniej jeden znak) na -. Więc to wypisuje -dla tych trzech przypadków i nic innego.

D`\w+
 .

To dwa kolejne etapy. Pierwszy etap to Deduplikacja. Dopasowuje słowa i usuwa duplikaty. Więc jeśli i tylko jeśli dane wejściowe to remis, to spada drugie słowo.

Drugi etap liczy liczbę dopasowań ., po których następuje dowolna postać. Jeśli dane wejściowe były remisowe, a drugie słowo zostało usunięte, skutkuje to 0. W przeciwnym razie drugie słowo jest nadal na swoim miejscu i istnieje jedno dopasowanie, więc drukowane jest 1zamiast niego.

Martin Ender
źródło
Oto inne podejście oparte na długości łańcucha wejściowego. Jest dłuższy niż twój, ale zastanawiam się, czy można by go jeszcze zagrać w golfa?
Cyfrowy uraz
@DigitalTrauma to naprawdę fajny pomysł, ale nie widzę nic, co mogłoby go skrócić. Myślę, że powinieneś go mimo to opublikować (a jeśli przeniesiesz pierwszą linię do nagłówka, TIO nie uwzględni jej w liczbie bajtów).
Martin Ender
8

05AB1E , 18 17 15 10 9 bajtów

6 bajtów zapisanych dzięki sztuczce długości wejściowej Digital Trauma

€g3^Æ>3%<

Pobiera dane wejściowe jako [SecondPlayersChoice,FirstPlayersChoice]

Wypróbuj online! lub Sprawdź poprawność wszystkich przypadków testowych

Alternatywne rozwiązanie 9-bajtowe: íø¬ÇÆ>3%<

Wyjaśnienie

€g          # length of each in input
  3^        # xor 3
    Æ       # reduce by subtraction
     >      # increment
      3%    # modulus 3
        <   # decrement

Poprzednie 15 bajtowe rozwiązanie

A-D{„PSÊiR}Ç`.S

Wypróbuj online! lub Sprawdź poprawność wszystkich przypadków testowych

Wyjaśnienie

 A-               # remove the lowercase alphabet from the input (leaves a 2 char string)
   D{             # sort a copy of the leftover
     „PSÊ         # check if the copy isn't "PS" (our special case)
         iR}      # if true, reverse the string to get the correct sign
            Ç`    # convert the two letters to their character codes
              .S  # compare their values
Emigna
źródło
Pokonałeś moją zabawną :( Ç¥13T/*.½òDLACZEGO TO DZIAŁA? NIKT NIE WIE.
Magic Octopus Urn
@MagicOctopusUrn: Uuuh, to z pewnością dziwne. Jaki byłby format wejściowy, aby zwracał wartość int jako wynik?
Emigna
['R','P']: P To jest część tego.
Magic Octopus Urn
@MagicOctopusUrn: O tak, zapomniałem o tym. Moja ulubiona odpowiedź na to wyzwanie :)
Emigna
6

Galaretka , 8 bajtów

L€Iµ-*×Ṡ

Wypróbuj online! (pakiet testowy, dla zachowania przejrzystości rzutuje na liczbę całkowitą)

Jak to działa

L€Iµ-*×Ṡ  Main link. Argument: A (string array)

L€        Take the length of each string.
  I       Increments; compute the forward difference of the length.
   µ      Begin a new chain with the difference d as argument.
    -*    Compute (-1)**d.
      ×Ṡ  Multiply the result with the sign of d.
Dennis
źródło
6

Python 2 , 46 40 bajtów

lambda x,y:+(x!=y,-1)[x[0]+y[0]in'RPSR']

Wypróbuj online!

Podziękowania dla @Dennis za umożliwienie mi pożyczenia jego kodu testowego Wypróbuj online i za zaoszczędzenie mi 6 bajtów.

Edytować

@ hashcode55 - W zasadzie tak, jak to opisujesz. (x! = y, -1) to sekwencja dwóch elementów, a [x [0] + y [0] w 'RPSR'] oblicza, który element wziąć. Jeśli pierwsza litera x + pierwsza litera y znajduje się na liście znaków, to zwróci wartość True lub 1, więc (x! = Y, -1) [1] zostanie zwrócona. Jeśli tak nie jest, to (x! = Y, -1) [0]. To staje się nieco trudne. Pierwszy element sam w sobie jest skutecznie kolejnym, jeśli. Jeżeli x! Znak + jest nieco podstępny i jeszcze raz dziękuję @Dennis za ten. X! = Y zwróci dosłowne Prawda lub Fałsz. Potrzebujemy 1 lub 0. Nadal nie wiem jak, ale + dokonuje tej konwersji. Mogę tylko założyć, że użycie operatora matematycznego na True / False wymusza postrzeganie go jako liczby całkowitej. Oczywiście + przed -1 nadal zwróci -1.

Mam nadzieję że to pomoże!

ElPedro
źródło
Cześć! Czy możesz mi powiedzieć, jak działa ta składnia? Logiczne zgadywanie, (x!=y,-1)działa to tak, jakby jeśli lista wygenerowała wartość true, wówczas -1 x!=y. Jaki jest użytek z tego +znaku? Bardzo pomocne byłoby źródło dokumentujące tego rodzaju składnię!
hashcode55
@ hashcode55 - Do mojej odpowiedzi dodałem wyjaśnienie.
ElPedro
Aby odpowiedzieć na twoją niepewność związaną z +- w tym przypadku jest to jednoznaczny plus +10, i zasadniczo jest to krótki sposób na konwersję na liczbę całkowitą.
FlipTack,
Dzięki @FlipTack. Trochę zgadłem, że tak właśnie działa, ale dziękuję za właściwe wyjaśnienie.
ElPedro
@ElPedro Wielkie dzięki! To mi naprawdę pomogło.
hashcode55
5

JavaScript (ES6), 46 38 bajtów

(a,b)=>(4+!b[4]+!b[5]-!a[4]-!a[5])%3-1

Wykorzystuje fakt, że Rock-Paper-Scissors jest cykliczny. JavaScript nie ma ani statku kosmicznego, ani zrównoważonych operatorów trójskładnikowych, w przeciwnym razie odpowiedź byłaby (a,b)=>((b<=>'Rock')-(a<=>'Rock'))%%3.

Edycja: Zapisano 8 bajtów dzięki @WashingtonGuedes.

Neil
źródło
1
@WashingtonGuedes Mogę zrobić jeszcze lepiej!
Neil
Możesz curry, aby zapisać 1 bajt
MayorMonty
próbowałem go uruchomić i zawsze
zwracałem
5

MATL , 14 13 bajtów

TTt_0vic1Z)d)

Wypróbuj online! Lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie

Jeśli kod ASCII pierwszej litery pierwszego ciągu zostanie odjęty od kodu drugiego ciągu, otrzymamy wartość w kolumnie D poniżej. Biorąc modulo 5 daje wartość M . Końcowa wartość w nawiasie to pożądany efekt, R .

                        D        M     R
                       ---      ---   ---
Rock Rock          ->   0   ->   0   ( 0) 
Rock Paper         ->  −2   ->   3   (−1)
Rock Scissors      ->   1   ->   1   ( 1)
Paper Rock         ->   2   ->   2   ( 1)
Paper Paper        ->   0   ->   0   ( 0)
Paper Scissors     ->   3   ->   3   (−1)
Scissors Rock      ->  −1   ->   4   (−1)
Scissors Paper     ->  −3   ->   2   ( 1)
Scissors Scissors  ->   0   ->   0   ( 0)

Zatem jeśli obliczymy D, a następnie M , aby uzyskać R, musimy tylko odwzorować 0 na 0; 1 i 2–1; 3 i 4 do -1. Można tego dokonać poprzez indeksowanie do tablicy pięciu wpisów równych 0, 1 lub -1. Ponieważ indeksowanie w MATL jest oparte na 1 i modułowe, tablica powinna być [1, 1, −1, −1, 0](pierwszy wpis ma indeks 1, ostatni indeks 5 lub równoważnie 0). Wreszcie, można na szczęście uniknąć operacji modulo 5, ponieważ jest ona domyślnie przeprowadzana przez indeksowanie modułowe.

TT     % Push [1 1]
t_     % Duplicate, negate: pushes [−1 −1]
0      % Push 0
v      % Concatenate vertically into the 5×1 array [1; 1; −1; −1; 0]
i      % Input cell array of strings
c      % Convert to 2D char array, right-padding with zeros if necessary
1Z)    % Take the first column. Gives a 2×1 array of the initial letters
d      % Difference
)      % Index into array. Implicit display
Luis Mendo
źródło
5

CJam , 12 bajtów

0XXWW]rcrc-=

Dwa wejścia są oddzielone spacją. Ich kolejność jest odwrócona w stosunku do tej w tekście wyzwania.

Wypróbuj online! Lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie

Tłumaczenie mojej odpowiedzi MATL . Wykorzystuje to fakt, że w CJam c(konwersja na char) zastosowane do łańcucha przyjmuje swój pierwszy znak. Również tablica mapowania jest inna, ponieważ indeksowanie w CJam opiera się na 0.

0XXWW    e# Push 0, 1, 1, -1, -1
]        e# Pack into an array
rc       e# Read whitespace-separated token as a string, and take its first char
rc       e# Again
-        e# Subtract code points of characters
=        e# Index into array. Implicitly display
Luis Mendo
źródło
5

CJam, 15 14 12 bajtów

rW=rW=-J+3%(

Weź kod ascii ostatniego znaku każdego łańcucha, a następnie zwróci:

(a1 - a2 + 19) % 3 - 1

Sprawdź to tutaj !

Arnaud
źródło
4

Java 7, 82 bajty

int c(String...a){int x=(a[0].charAt(1)-a[1].charAt(1))%5/2;return x%2==x?x:x/-2;}

Nie golfowany:

int c(String... a){
   int x = (a[0].charAt(1) - a[1].charAt(1)) % 5 / 2;
   return x%2 == x
           ? x
           : x / -2;
}

Wyjaśnienie:

  • Drugi litery s o, ai c, z dziesiętnych ASCII 111, 97a 99.
  • Jeśli odejmiemy je od siebie dla przypadków testowych, otrzymamy następujące wyniki:
    • 0 (Rock, Rock)
    • 14 (Kamień, papier)
    • 12 (Papier, nożyczki)
    • -14 (Papier, kamień)
    • 0 (Papier, papier)
    • -2 (Papier, nożyczki)
    • -2 (Nożyczki, kamień)
    • 2 (Nożyczki, papier)
    • 0 (Nożyczki, nożyczki)
  • Jeśli weźmiemy modulo 5 dla każdego, otrzymujemy 4, 2, -4, -2, -2, 2.
  • Podzielone przez 2 xjest teraz dla przypadków testowych:
    • x = 0 (Rock, Rock)
    • x = 2 (kamień, papier)
    • x = 1 (papier, nożyczki)
    • x = -2 (papier, kamień)
    • x = 0 (papier, papier)
    • x = -1 (papier, nożyczki)
    • x = -1 (nożyce, kamień)
    • x = 1 (nożyczki, papier)
    • x = 0 (nożyczki, nożyczki)
  • Tylko 2i -2są błędne i powinno być -1i 1zamiast. Więc jeśli x%2 != x(wszystko powyżej 1lub poniżej -1) dzielimy przez, -2aby naprawić te dwa „przypadki brzegowe”.

Kod testowy:

Wypróbuj tutaj.

class M{
  static int c(String...a){int x=(a[0].charAt(1)-a[1].charAt(1))%5/2;return x%2==x?x:x/-2;}

  public static void main(String[] a){
    String R = "Rock",
           P = "Paper",
           S = "Scissors";
    System.out.println(c(R, R)); // 0
    System.out.println(c(R, P)); // -1
    System.out.println(c(R, S)); // 1
    System.out.println(c(P, R)); // 1
    System.out.println(c(P, P)); // 0
    System.out.println(c(P, S)); // -1
    System.out.println(c(S, R)); // -1
    System.out.println(c(S, P)); // 1
    System.out.println(c(S, S)); // 0
  }
}

Wynik:

0
-1
1
1
0
-1
-1
1
0
Kevin Cruijssen
źródło
Dlaczego drugi list z ciekawości? Miałem to samo podejście (trochę), ale użyłem pierwszego listu.
Magic Octopus Urn
@ carusocomputing Cóż, zauważyłem, że większość innych osób używała pierwszej litery lub długości i chciała spróbować czegoś innego. I po raz pierwszy użyty litery trzecie ( c, p, i) z wartości ASCII 99, 112i 105, jak wydawało się najbardziej przydatny, i zauważył, że to stać 4, 2, 0, jeśli zrobiłem modulo 5. Dopiero wtedy pomyślałem, musiałem odjąć obie, tak 4, 2 i 0 nie były zbyt przydatne. Po kilku nieudanych próbach / próbach i błędach spróbowałem drugiej litery i uzyskiwałem bardziej użyteczne wyniki z tym samym modulo 5 wciąż obecnym. Potem szybko doszedłem do rozwiązania, które przedstawiłem powyżej. :)
Kevin Cruijssen
@ carusocomputing Chciałem wypróbować unikalne podejście, a biorąc pod uwagę, że jestem dość zły w tego rodzaju rozwiązaniach, nie jest tak krótki jak niektóre inne rozwiązania, ale nadal jest wyjątkowy (co było moim pierwotnym celem). :)
Kevin Cruijssen
4

dc, 18

1?Z9+2/rZ1+2/-3%-p

Wypróbuj online .

Zauważ, że dwa argumenty są przekazywane (oddzielone spacjami) w jednym wierszu do STDIN. Argumenty są zawarte w nawiasach kwadratowych, [ ]ponieważ tak dcpodoba się jego łańcuchy.

dcma bardzo ograniczoną obsługę łańcuchów, ale okazuje się, że jedną z rzeczy, które możesz zrobić, jest użycie Zpolecenia, aby uzyskać długość łańcucha, która na szczęście jest różna dla „Rock”, „Paper” i „Scissors” i może być po prostu arytmetyczna zmanipulowane w celu uzyskania pożądanego rezultatu.

Cyfrowa trauma
źródło
4

PHP, 34 bajty

<?=md5("BMn$argv[1]$argv[2]")%3-1;
użytkownik63956
źródło
3

Pyth, 16 lat

t%+7h.+mx3ldQ3

Prawdopodobnie może być krótszy.

        x3ld      # lambda to get string length then XOR with 3
       m    Q     # map over the input (array of 2 strings)
     .+           # difference of the two results
    h             # flatten one-element array
  +7              # add 7
 %           3    # mod 3
t                 # subtract 1 and implicit print

Online .

Cyfrowa trauma
źródło
3

C #, 85 84 bajtów

Zapisano 1 bajt dzięki TheLethalCoder

a=>b=>a==b?0:(a[0]=='R'&b[0]=='S')|(a[0]=='P'&b[0]=='R')|(a[0]=='S'&b[0]=='P')?1:-1;

Akceptuje dwa ciągi jako dane wejściowe i generuje liczbę całkowitą. Remis, jeśli dwa struny są równe, w przeciwnym razie sprawdza pierwszy charachter strun, aby ustalić, który gracz wygra.

Horváth Dávid
źródło
Zaoszczędź jeden bajt, używając a=>b=>...
curry,
3

JavaScript, 37 , 32 , 31 bajtów

a=>b=>a==b?0:!(a+b)[12]^a>b||-1

Jeśli a jest równe b, wyprowadza zero.

W przeciwnym razie x lub wynik sprawdzenia, czy długość nie jest większa niż 12 (porównanie nożyczek i papieru) z porównaniem większej niż b.
Jeśli to zwraca 1, zwróć to.

Jeśli zwraca 0, użyj operatora OR, aby zastąpić -1.

Grax32
źródło
Czy możesz zapisać to jako funkcję curry, a=>b=>aby zapisać bajt?
FlipTack
Tak. Dziękuję @FlipTack
Grax32
2

Partia, 116 bajtów

@if %1==%2 echo 0&exit/b
@for %%a in (RockScissors PaperRock ScissorsPaper)do @if %%a==%1%2 echo 1&exit/b
@echo -1
Neil
źródło
2

Perl, 33 bajty

32 bajty kodu + -pflaga.

$_=/(.+) \1/?0:-/k P|r S|s R/||1

Aby uruchomić:

perl -pe '$_=/(.+) \1/?0:-/k P|r S|s R/||1' <<< "Rock Paper"

Zaoszczędzono 3 bajty, używając wyrażenia regularnego odpowiedzi Retina Martina Endera . (moim poprzednim wyrażeniem regularnym było /R.*P|P.*S|S.*R/)

Wyjaśnienie:

Najpierw /(.+) \1/sprawdza, czy dane wejściowe zawierają dwa razy to samo słowo, jeśli tak, wynikiem jest 0. W przeciwnym razie /k P|r S|s R/dotyczy przypadku, w którym znajduje się odpowiedź -1. Jeśli to ostatnie wyrażenie jest fałszywe, to -/k P|r S|s R/jest fałszywe, więc wracamy 1.

Dada
źródło
2

Galaretka , 9 bajtów

L€^3Iæ%1.

Wykorzystuje algorytm z odpowiedzi Bash @ DigitalTrauma .

Wypróbuj online!

Jak to działa

L€^3Iæ%1.  Main link. Argument: A (string array)

L€         Take the length of each string.
  ^3       XOR the lengths bitwise with 3.
    I      Increments; compute the forward difference of both results.
     æ%1.  Balanced modulo 1.5; map the results into the interval (-1.5, 1.5].
Dennis
źródło
Cholera, właśnie miałem zacząć czytać o Galaretce. No cóż, tutaj jest pyth . +1.
Digital Trauma
2

Japt , 19 bajtów

-Ms(4*(Uc -Vc)/MP¹r

Wypróbuj tutaj!

Zainspirowany rozwiązaniem carusocomputing

Stare 53-bajtowe rozwiązanie

W=Ug c X=Vg c W¥X?0:W¥82©X¥83?1:W¥80©X¥82?1:W¥83©X¥80?1:J

Wypróbuj online!

Jeszcze raz dziękuję, ETHproductions!

Oliver
źródło
1
Można zacząć stosując ©zamiast &&, zmieniając Ug0 cdo Ug c(samo V) i zastępowanie -1z J. Jest to jednak nieco dłużej niż odpowiedź JS , być może możesz wziąć z tego kilka pomysłów
ETHproductions
@ETHproductions Dzięki! Nie wiem, jak o tym zapomniałem©
Oliver,
1
Właściwie możesz to zrobić W=Uc. Nie wiem, dlaczego ciągle zapominam, że cdziała na dowolnym łańcuchu: P
ETHproductions
2

PHP, 55 53 bajtów

<?=(3-(ord($argv[2])%6%4-ord($argv[1])%6%4+3)%3*2)%3;
  • przyjmuje wartości ascii pierwszych liter (z argumentów wiersza poleceń): 82,80,83
  • % 6: 4,2,5
  • % 4: 0,2,1
  • różnica (ba):
    • PS: 1-2, SR: 2-0, RP: 2-0 -> -1 lub 2; + 3,% 3 -> 2
    • SP: 2-1, RS: 0-2, PR: 0-2 -> -2 lub 1; + 3,% 3 -> 1
    • RR, PP, SS: 0; + 3,% 3: 0
  • (3-2 * x): -1,1,3
  • % 3: -1,1,0

wersja sinusoidalna, 49 46 bajtów

<?=2*sin(1.3*(ord($argv[2])-ord($argv[1])))|0;

odpowiedź golfa w carusocomputing :

3 bajty zapisane przez @ user59178

Tytus
źródło
1
W wersji dla sinusoidalnej można zapisać 3 bajty zastępując round(x)z2*x^0
user59178
2

Perl, 25 bajtów

$_=/kS|rR|sP/-/kP|rS|sR/

Kod 24 bajty +1 bajt dla -popcji.

Wejście powinno być ustawione na standardowe wejście bez separatorów, np .:

echo PaperRock | perl -pe'$_=/kS|rR|sP/-/kP|rS|sR/'

Pierwsze wyrażenie regularne szuka wygranej pierwszego gracza, drugie przegranej. Różnica jest drukowana.

mik
źródło
1

Scala, 148 bajtów

object R extends App{val t=Seq('R','P','S')
val(a,b)=(args(0)(0),args(1)(0))
print(if(a==b)0 else if(t.indexOf(a)%3==(t.indexOf(b)-1)%3)-1 else 1)}

Na szczęście, ponieważ średniki są wymagane do oddzielenia wielu poleceń w tej samej linii, Scala korzysta z formatowalnego kodu golfowego!

W tej próbie golfa nauczyłem się, że możesz go wymienić

"somestring".charAt(index) 

z

"somestring"(index) 

ponieważ Scala pozwala traktować ciągi jako tablice w celu uzyskania znaków.

Arcymag
źródło
Można to ogromnie zagrać w golfa. Na początek możesz wykonać funkcję zamiast kompletnego programu w większości wyzwań tutaj, więc zamiast całego obiektu rozszerza aplikację i wyciąga z argumentów, spróbuj czegoś takiego: def g (a: Seq, b: Seq) = ...
Ethan
Ponadto nie musisz drukować wartości. Zwrot jest wystarczający, co jest świetne, gdy grasz w golfa Scala, ponieważ zwrot jest bezpłatny. Możesz go jeszcze bardziej ulepszyć, korzystając ze sztuczki zamieszczonej w odpowiedzi Groovy, która działa prawie identycznie w Scali.
Ethan