Ai sẽ thắng một trò chơi Rock, Paper, Kéo, Lizard, Spock?


24

một số câu hỏi liên quan đến trò chơi này , thậm chí là một cuộc thi ở đây . Nhưng tôi nghĩ rằng tất cả những thử thách và cuộc thi đó cần một cách để tự động xác định người chiến thắng trong trò chơi. Vì thế:

Thử thách

Đưa ra hai đầu vào trong phạm vi ["rock", "paper", "scissors", "lizard", "spock"]đại diện cho các lựa chọn cho người chơi 1 và người chơi 2, xác định người chiến thắng trong trận đấu.

Quy tắc

[Winner] [action]    [loser]
-----------------------------
scissors cut         paper
paper    covers      rock
rock     crushes     lizard
lizard   poisons     spock
spock    smashes     scissors
scissors decapitates lizard
lizard   eats        paper
paper    disproves   spock
spock    vaporizes   rock
rock     crushes     scissors

Hạn chế

  • Đầu vào sẽ là một cặp chuỗi trong phạm vi đã cho (không thể sử dụng chuỗi nào khác). Bạn có thể sử dụng mảng ký tự nếu muốn, miễn là chúng đại diện cho bất kỳ giá trị nào được đề cập.
  • Bạn có thể chọn sử dụng chữ thường, chữ hoa ( "ROCK") hoặc vỏ lạc đà ( "Rock") cho các chuỗi đầu vào, miễn là trường hợp được chọn là giống nhau cho tất cả các đầu vào.
  • Đầu ra sẽ là một bộ ba giá trị quyết định người chiến thắng, có thể là bất cứ điều gì bạn muốn miễn là câu trả lời nhất quán. Ví dụ: 1nếu đầu vào thứ nhất thắng, 2nếu đầu vào thứ hai thắng, 0nếu có hòa. Hoặc có thể Anếu đầu vào thứ nhất thắng, Bnếu đầu vào thứ hai thắng, <empty string>nếu có hòa.

Mục tiêu

Đây là , vì vậy có thể chương trình / phương pháp / chức năng / lambda ngắn nhất cho mỗi ngôn ngữ sẽ giành chiến thắng!

Xét nghiệm

[Input 1] [Input 2] [Output: 1/2/0]
-----------------------------------
 rock      paper     2
 rock      scissors  1
 lizard    spock     1
 spock     rock      1
 spock     paper     2
 rock      rock      0

Điều này đến từ hộp cát .
Charlie


Tôi đã đóng nó như một bản sao của câu hỏi được liên kết vì nó chỉ là cùng một câu hỏi với 2 giá trị mới và một biến thể nhỏ trên IO.
Thuật sĩ lúa mì

4
@WheatWizard đôi khi một thay đổi nhỏ trong đầu vào tạo ra các đầu ra rất khác nhau. Các câu hỏi có thể khá giống nhau nhưng hai giá trị mới tạo ra nhiều trường hợp cần xem xét, vì vậy các thuật toán được sử dụng ở đây đủ khác nhau để khiến mọi người phải suy nghĩ lại (xem câu trả lời với cakemẹo).
Charlie

4
Tôi đồng ý, và bỏ phiếu để mở lại.
GB

Câu trả lời:


25

Python 3 , 68 50 48 byte

EDIT: Nhờ 3 thủ thuật của Neil và 2 từ Mr. Xcoder

Mỗi chuỗi đầu vào có một ký tự thứ tư riêng biệt, vì vậy tôi đang sử dụng chuỗi đó để phân biệt chúng. Nếu bạn sắp xếp các phần tử trong chu trình (kéo, giấy, đá, thằn lằn, spock), thì mỗi phần tử sẽ đánh bại phần tử ngay sau nó và phần tử 3 điểm bên phải, theo chu kỳ. Vì vậy, chúng tôi trừ các vị trí của đầu vào trong chu kỳ. Nếu số đó là 0, thì đó là hòa. Nếu là 1 hoặc 3, đó là chiến thắng cho người chơi đầu tiên. Trong giải pháp ban đầu của tôi, sự khác biệt về chu kỳ sẽ lập chỉ mục trong chuỗi "210100" để phân biệt kết quả của trò chơi. Neil bằng cách nào đó đã tìm ra điều này có thể được thực hiện mà không cần lập chỉ mục bằng cách thêm 7 và lấy mô đun bằng 3. Chỉnh sửa: Ban đầu tôi đã sử dụng ký tự thứ hai để xác định chuỗi, nhưng nếu bạn sử dụng chuỗi thứ tư và đảo ngược chu kỳ, bạn sẽ nhận được bánh. Và tất cả chúng ta có thể sử dụng nhiều bánh hơn.

lambda x,y,z="cake".find:(7+z(y[3])-z(x[3]))%5%3

Hãy thử trực tuyến!

Phiên bản cũ hơn:

lambda x,y,z="caoip".index:(7+z(y[1])-z(x[1]))%5%3

Hãy thử trực tuyến!

Phiên bản gốc:

b="caoip"
def r(x,y):return"210100"[(b.index(y[1])-b.index(x[1]))%5]

Hãy thử trực tuyến!



6
Chào mừng đến với PPCG!
Steadybox

1
49 byte: Hãy thử trực tuyến! (chuyển .indexsang .find)
Ông Xcoder

1
48 byte: Hãy thử trực tuyến! (bạn không cần p, "chaoi"đủ)
Ông Xcoder

14

JavaScript (ES6), 56 byte

Đưa đầu vào theo cú pháp currying (a)(b). Trả về 0nếu A thắng, 1nếu B thắng hoặc falsehòa.

a=>b=>a!=b&&a>b^614>>((g=s=>parseInt(s,31)%9)(a)^g(b))&1

Bản giới thiệu

Làm sao?

Chúng tôi định nghĩa hàm băm H () là:

H = s => parseInt(s, 31) % 9

Điều này mang lại:

s          | H(s)
-----------+-----
"rock"     |  2
"paper"    |  8
"scissors" |  1
"lizard"   |  3
"spock"    |  4

Cho hai đầu vào ab , chúng tôi xem xét các tuyên bố sau:

  1. chúng ta có a> b không? (theo thứ tự từ điển)
  2. không b giành chiến thắng trong trò chơi?
  3. giá trị của N = H (a) XOR H (b) là bao nhiêu?

Từ (1) và (2), chúng tôi suy luận xem kết quả của a> b có nên được đảo ngược để có được người chiến thắng chính xác hay không và chúng tôi lưu trữ cờ này trong bit N- bit của tra cứu bitmask.

a        | H(a) | b        | H(b) | N  | a > b | b wins | invert
---------+------+----------+------+----+-------+--------+-------
rock     |   2  | paper    |   8  | 10 | Yes   | Yes    | No
rock     |   2  | scissors |   1  |  3 | No    | No     | No
rock     |   2  | lizard   |   3  |  1 | Yes   | No     | Yes
rock     |   2  | spock    |   4  |  6 | No    | Yes    | Yes
paper    |   8  | rock     |   2  | 10 | No    | No     | No
paper    |   8  | scissors |   1  |  9 | No    | Yes    | Yes
paper    |   8  | lizard   |   3  | 11 | Yes   | Yes    | No
paper    |   8  | spock    |   4  | 12 | No    | No     | No
scissors |   1  | rock     |   2  |  3 | Yes   | Yes    | No
scissors |   1  | paper    |   8  |  9 | Yes   | No     | Yes
scissors |   1  | lizard   |   3  |  2 | Yes   | No     | Yes
scissors |   1  | spock    |   4  |  5 | No    | Yes    | Yes
lizard   |   3  | rock     |   2  |  1 | No    | Yes    | Yes
lizard   |   3  | paper    |   8  | 11 | No    | No     | No
lizard   |   3  | scissors |   1  |  2 | No    | Yes    | Yes
lizard   |   3  | spock    |   4  |  7 | No    | No     | No
spock    |   4  | rock     |   2  |  6 | Yes   | No     | Yes
spock    |   4  | paper    |   8  | 12 | Yes   | Yes    | No
spock    |   4  | scissors |   1  |  5 | Yes   | No     | Yes
spock    |   4  | lizard   |   3  |  7 | Yes   | Yes    | No

Do đó các bit:

bit | value
----+-----------
 0  | 0 (unused)
 1  | 1
 2  | 1
 3  | 0
 4  | 0 (unused)
 5  | 1
 6  | 1
 7  | 0
 8  | 0 (unused)
 9  | 1
10  | 0
11  | 0
12  | 0

Đọc điều này từ dưới lên trên và bỏ qua các số 0 đứng đầu, điều này mang lại 1001100110 , hoặc 614 ở dạng thập phân.



4

JavaScript (ES6), 63 54 53 49 byte

f=
(l,r,g=s=>"cake".search(s[3]))=>(7+g(r)-g(l))%5%3
<div onchange=o.textContent=`RLT`[f(a.selectedOptions[0].value,b.selectedOptions[0].value)]>L: <select id=a><option>Rock<option>Paper<option>Scissors<option>Lizard<option>Spock</select> R: <select id=b><option>Rock<option>Paper<option>Scissors<option>Lizard<option>Spock</select> Winner: <span id=o>T

Cổng golf của tôi để @ WhatToDo trả lời. Lưu ý: đoạn mã giải mã kết quả số thành một cái gì đó ít đọc hơn. Chỉnh sửa: Đã lưu 1 byte nhờ @Arnauld. Đã lưu 4 byte nhờ @ovs.


@ovs Ugh, tôi đã không chuyển câu lạc bộ golf của mình sang câu trả lời của WhatToDo đủ mạnh ...
Neil

3

Ruby , 36 byte

->a,b{(2+a.sum%88%6-b.sum%88%6)%5%3}

Trả về 0nếu người chơi thứ 1 thắng, 1nếu người chơi thứ 2 thắng và được 2bốc thăm.

Dựa trên câu trả lời của user507295 nhưng sử dụng công thức toán học để thực hiện hàm băm. a.sumlà tổng của tất cả các mã ASCII của chuỗi a, mod 1<<16và được dùng như một tổng kiểm tra thô sơ. Băm được tìm thấy bằng cách sử dụng mã sau đây:

1.upto(99){|j|p j,["scissors","paper","rock","lizard","spock"].map{|i|i.sum%j%6}}

Điều này tạo ra hai giá trị jđã tạo ra một hàm băm phù hợp cho các chữ cái viết thường, cụ thể là 88 và 80, cả hai đều đưa ra chuỗi giảm dần [3,2,1,0,4](hoặc [4,3,2,1,0]nếu spock được quay vòng từ đầu.)

Như đã giải thích trong các câu trả lời khác, một hàm băm tạo ra sự khác biệt không đổi modulo 5 cho các phần tử liên tiếp trong chuỗi trên là cần thiết để làm cho (h[a]-h[b])%5công thức hoạt động. Mỗi phần tử đánh bại phần tử 1 hoặc 3 vị trí bên phải và thua phần tử 2 hoặc 4 vị trí bên phải.

Hãy thử trực tuyến!


3

C, 53byte

a="FÈ..J..ÁE";
z=*++y==*++x?0:a[*y&47>>1]>>*++x&7&1+1;

Tôi đã coi vấn đề này là một máy trạng thái, trong đó có 25 trạng thái được xác định bởi hai, năm đầu vào trạng thái.

Bằng cách xác định kết quả của các trạng thái trong một mảng bit. Tôi tìm kiếm kết quả bên trong bằng cách sử dụng các dấu hiệu duy nhất trong các đầu vào.

Như đã lưu ý trong các giải pháp khác, các ký tự 2, 3 và 4 là duy nhất giữa các đầu vào có thể. Tôi đã tập trung sử dụng vào các ký tự 2 và 3 mà tôi sử dụng để chọn bit thích hợp trong mảng câu trả lời của mình.

Trong Ký tự 2, các bit 1 đến 4 xác định rõ đầu vào. Bằng cách che dấu các bit này và dịch chuyển một cách thích hợp [đó là "* y & 47 >> 1"], đầu vào có thể được ghi chú là 0, 1, 4, 7 hoặc 8. Do đó, chuỗi câu trả lời của tôi có 9 ký tự. (tách các bit thú vị)

character 2:
a 61   011 0000 1
c 63   011 0001 1
i 69   011 0100 1
p 70   011 1000 0
o 6f   011 0111 1

Trong ký tự 3, các bit 0, 1 và 2 xác định rõ đầu vào. Bằng cách che các bit này (không cần dịch chuyển) [đó là "* x & 7"], đầu vào có thể được ghi chú là 0, 1, 2, 3 hoặc 7. (tách các bit thú vị)

character 3
p 70   01110 000
i 69   01101 001
z 7a   01111 010
o 6f   01101 111
c 63   01100 011

Chuỗi câu trả lời sau đó có thể được tính bằng cách chỉ cần điền vào các bit cho các ký tự thích hợp.

0th char represents X=paper
1st char represents X=scissors
4th char represents X=Lizard
7th char represents X=Rock
8th char represents X=Spock

0th bit represents Y=Paper
1st bit represents Y=Scissors
2nd bit represents Y=Lizard
3rd bit represents Y=Rock
7th bit represents Y=Spock

Vì vậy, đặt bit trong char nơi Y thắng

char  7654 3210   in hex    in ascii
0     0100 0110    46         F
1     1100 1000    c8         È
2     0100 0000    d/c        .
3     0100 0000    d/c        .
4     0100 1010    4a         J
5     0100 0000    d/c        .
6     0100 0000    d/c        .
7     1100 0001    c1         Á
8     0100 0101    45         E

Sau đó, logic đơn giản là: nếu char thứ hai giống nhau thì vẽ, nếu không, hãy lấy ascii char dựa trên ký tự thứ hai của y và dịch chuyển bit theo ký tự thứ ba của x và thêm một. Điều này làm cho các câu trả lời 0 cho trận hòa, 1 cho x thắng và 2 cho y thắng.


Chào mừng đến với PPCG! Đây là một câu trả lời tuyệt vời, chu đáo.
FantaC

1

Clojure, 130 118 byte

-12 byte bằng cách loại bỏ việc sử dụng kỳ lạ của tôi comp.

(fn[& m](let[[p q](map #(apply +(map int(take 2 %)))m)d(- p q)](cond(= d 0)0(#{5 -16 12 -14 13 1 4 -18 2 11}d)1 1 2)))

Tôi nghĩ rằng tôi đã thông minh, nhưng điều này cuối cùng là ngây thơ so với một số câu trả lời khác, và lâu hơn nhiều .

Lấy 2 chữ cái đầu tiên của mỗi chuỗi di chuyển, lấy mã char và tính tổng chúng. Sau đó, nó trừ đi số tiền để có được d. Nếu dlà 0, thì đó là hòa (0), nếu là trong tập hợp #{5 -16 12 -14 13 1 4 -18 2 11}, p1 thắng (1), khác, p2 thắng (2).

(defn decide [& moves] ; Using varargs so I don't need to duplicate the steps.
  ; Pop the first 2 chars of each string, convert them to their ASCII code, and sum them.
  (let [[p1 p2] (map #(apply + (map int (take 2 %))) moves)
        d (- p1 p2)]

    (cond
      (= d 0) ; A tie
      0

      (#{5 -16 12 -14 13
         1 4 -18 2 11} d) ; P1 Wins
      1

      :else ; P2 Wins
      2)))

Để có được "số ma thuật" xác định nếu P1 thắng, tôi đã chạy

(let [ms ["rock", "paper", "scissors", "lizard", "spock"]]
  (for [p1 ms
        p2 ms]

    ; Same as above
    (let [[p q] (map #(apply + (map int (take 2 %))) [p1 p2])
          d (- p q)]

      [p1 p2 d])))

Tạo danh sách các dgiá trị cho từng kịch bản có thể:

(["rock" "rock" 0]
 ["rock" "paper" 16]
 ["rock" "scissors" 11]
 ["rock" "lizard" 12]
 ["rock" "spock" -2]
 ["paper" "rock" -16]
 ["paper" "paper" 0]
 ["paper" "scissors" -5]
 ["paper" "lizard" -4]
 ["paper" "spock" -18]
 ["scissors" "rock" -11]
 ["scissors" "paper" 5]
 ["scissors" "scissors" 0]
 ["scissors" "lizard" 1]
 ["scissors" "spock" -13]
 ["lizard" "rock" -12]
 ["lizard" "paper" 4]
 ["lizard" "scissors" -1]
 ["lizard" "lizard" 0]
 ["lizard" "spock" -14]
 ["spock" "rock" 2]
 ["spock" "paper" 18]
 ["spock" "scissors" 13]
 ["spock" "lizard" 14]
 ["spock" "spock" 0])

Sau đó, tôi so sánh biểu đồ giành chiến thắng với sản lượng này. May mắn thay, không có bất kỳ "va chạm" nào khác ngoài 0.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.