ใครจะชนะเกมร็อค, กระดาษ, กรรไกร, จิ้งจก, สป็อค?


24

มีหลายคำถามเกี่ยวกับเกมนี้แม้จะเป็นประกวดที่นี่ แต่ฉันคิดว่าความท้าทายและการแข่งขันทั้งหมดนั้นต้องการวิธีในการตัดสินผู้ชนะของเกมโดยอัตโนมัติ ดังนั้น:

ท้าทาย

เมื่อได้รับสองอินพุตในช่วงที่["rock", "paper", "scissors", "lizard", "spock"]เป็นตัวเลือกสำหรับผู้เล่น 1 และผู้เล่น 2 ให้พิจารณาผู้ชนะของการแข่งขัน

กฎระเบียบ

[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

ข้อ จำกัด

  • อินพุตจะเป็นคู่ของสตริงในช่วงที่กำหนด (ไม่สามารถใช้สตริงอื่นได้) คุณสามารถใช้อาร์เรย์ของตัวอักษรหากคุณต้องการตราบใดที่พวกเขาเป็นตัวแทนของค่าใด ๆ ที่กล่าวถึง
  • คุณสามารถเลือกได้ว่าจะใช้ตัวพิมพ์เล็ก, ตัวพิมพ์ใหญ่ ( "ROCK") หรือตัวอูฐ ( "Rock") สำหรับสตริงอินพุตตราบใดที่ตัวพิมพ์ที่เลือกนั้นเหมือนกันสำหรับอินพุตทั้งหมด
  • ผลลัพธ์จะเป็นสามค่าที่กำหนดผู้ชนะซึ่งสามารถเป็นอะไรก็ได้ที่คุณต้องการตราบใดที่คำตอบมีความสอดคล้องกัน ตัวอย่าง: 1ถ้าอินพุทแรกชนะ2ถ้าอินพุทที่สองชนะ0ถ้ามีเน็คไท หรือบางทีAถ้าอินพุทแรกชนะBถ้าอินพุทที่สองชนะ<empty string>ถ้ามีการเสมอ

เป้าหมาย

นี่คือดังนั้นโปรแกรม / วิธี / ฟังก์ชัน / แลมบ์ดาที่สั้นที่สุดสำหรับแต่ละภาษาจะชนะ!

การทดสอบ

[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

นี้มาจากกล่องเครื่องมือ
Charlie

1
ที่เกี่ยวข้องมาก
Stewie Griffin

ฉันได้ปิดมันเป็นคำถามที่ซ้ำกันของคำถามที่เชื่อมโยงเพราะเป็นเพียงคำถามเดียวกันกับ 2 ค่าใหม่และการเปลี่ยนแปลงเล็กน้อยใน IO
ข้าวสาลีตัวช่วยสร้าง

4
@WheatWizard บางครั้งการเปลี่ยนแปลงเล็กน้อยในอินพุตจะสร้างเอาต์พุตที่แตกต่างกันมาก คำถามอาจจะค่อนข้างคล้ายกัน แต่ค่าใหม่สองค่าสร้างกรณีเพิ่มเติมเพื่อพิจารณาดังนั้นอัลกอริทึมที่ใช้ที่นี่แตกต่างกันพอที่จะทำให้ผู้คนคิดอีกครั้ง (ดูคำตอบด้วยcakeเคล็ดลับ)
ชาร์ลี

4
ฉันเห็นด้วยและโหวตให้เปิดใหม่
GB

คำตอบ:


25

Python 3 , 68 50 48 ไบต์

แก้ไข: ขอบคุณ 3 เทคนิคจาก Neil และ 2 จาก Mr. Xcoder

สตริงอินพุตแต่ละตัวมีอักขระตัวที่สี่ที่แตกต่างกันดังนั้นฉันจึงใช้มันเพื่อแยกแยะพวกเขา หากคุณจัดเรียงองค์ประกอบในรอบ (กรรไกร, กระดาษ, หิน, จิ้งจก, สป็อค) จากนั้นแต่ละองค์ประกอบเต้นองค์ประกอบโดยตรงหลังจากนั้นและองค์ประกอบ 3 จุดไปทางขวา cyclically ดังนั้นเราจึงลบตำแหน่งของอินพุตในวง ถ้าตัวเลขนั้นคือ 0 มันคือเน็คไท หากเป็น 1 หรือ 3 จะเป็นชัยชนะสำหรับผู้เล่นคนแรก ในโซลูชันดั้งเดิมของฉันความแตกต่างของวงรอบจะจัดทำดัชนีเป็นสตริง "210100" เพื่อแยกแยะผลลัพธ์ของเกม นีลสามารถหาสิ่งนี้ได้โดยไม่ต้องทำดัชนีโดยการเพิ่ม 7 และรับโมดูลัสโดย 3 แก้ไข: เดิมฉันใช้อักขระตัวที่สองเพื่อระบุสตริง แต่ถ้าคุณใช้รอบที่สี่และย้อนกลับรอบคุณจะได้เค้ก และเราทุกคนสามารถใช้เค้กได้มากขึ้น

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

ลองออนไลน์!

รุ่นเก่ากว่า:

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

ลองออนไลน์!

รุ่นเดิม:

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

ลองออนไลน์!



6
ยินดีต้อนรับสู่ PPCG!
Steadybox

1
49 ไบท์: ลองออนไลน์! (เปลี่ยน.indexเป็น.find)
Mr. Xcoder

1
48 ไบต์: ลองออนไลน์! (คุณไม่จำเป็นต้องp, "chaoi"พอเพียง)
นาย Xcoder

14

JavaScript (ES6), 56 ไบต์

(a)(b)จะเข้าในไวยากรณ์ currying ส่งคืน0ถ้า A ชนะ1ถ้า B ชนะหรือfalseเป็นเสมอ

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

การสาธิต

อย่างไร?

เรากำหนดฟังก์ชันแฮชH ()เป็น:

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

สิ่งนี้ให้:

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

ให้สองอินพุตaและbเราพิจารณาข้อความต่อไปนี้:

  1. เรามี> bหรือไม่ (เรียงตามคำศัพท์)
  2. ไม่ชนะเกม?
  3. ค่าของN = H (a) XOR H (b)คืออะไร

จาก (1) และ (2) เราอนุมานว่าผลลัพธ์ของa> bควรกลับด้านเพื่อให้ได้ผู้ชนะที่ถูกต้องหรือไม่และเราเก็บธงนี้ไว้ในบิตNค้นหาครั้งที่สาม

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

ดังนั้นบิต:

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

อ่านจากล่างขึ้นบนและไม่สนใจศูนย์นำหน้านี่จะให้1001100110หรือ614 เป็นทศนิยม



4

JavaScript (ES6), 63 54 53 49 ไบต์

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

พอร์ตกอล์ฟของฉันไปที่คำตอบของ @ WhatToDo หมายเหตุ: ตัวอย่างจะถอดรหัสผลลัพธ์ที่เป็นตัวเลขเป็นสิ่งที่อ่านไม่ได้เล็กน้อย แก้ไข: บันทึก 1 ไบต์ขอบคุณ @Arnauld บันทึกแล้ว 4 ไบต์ขอบคุณ @ovs


@ovs ฮึฉันไม่ได้พอร์ตกอล์ฟของฉันที่จะตอบยากพอ WhatToDo ของ ...
นีล

3

Ruby , 36 ไบต์

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

ผลตอบแทน0ถ้าผู้เล่นคนแรกชนะ1ถ้าผู้เล่นคนที่สองชนะและ2เสมอ

ตามคำตอบของผู้ใช้ 507295 แต่ใช้สูตรทางคณิตศาสตร์เพื่อทำการแฮช a.sumคือผลรวมของรหัส ASCII ทั้งหมดของสตริงตัวaดัดแปลง1<<16และมีจุดประสงค์เพื่อตรวจสอบเบื้องต้น พบแฮชโดยใช้รหัสต่อไปนี้:

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

สิ่งนี้สร้างสองค่าของ jที่ให้แฮชที่เหมาะสมสำหรับตัวอักษรตัวพิมพ์เล็ก ได้แก่ 88 และ 80 ซึ่งทั้งคู่ให้ลำดับจากมากไปหาน้อย[3,2,1,0,4](หรือ[4,3,2,1,0]ถ้าสป็อคถูกขี่จักรยานไปจนถึงจุดเริ่มต้น)

ดังที่อธิบายไว้ในคำตอบอื่น ๆ การแฮชที่ให้โมดูโล 5 แตกต่างกันอย่างต่อเนื่องสำหรับองค์ประกอบต่อเนื่องในลำดับข้างต้นจำเป็นต้องทำให้ (h[a]-h[b])%5สูตรทำงานได้ แต่ละองค์ประกอบจะตีองค์ประกอบที่ 1 หรือ 3 ทางด้านขวาและจะสูญเสียองค์ประกอบที่ 2 หรือ 4 ไปทางขวา

ลองออนไลน์!


3

C, 53bytes

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

ฉันถือว่าปัญหานี้เป็นเครื่องสถานะซึ่งมี 25 สถานะตามที่กำหนดโดยอินพุตสองสถานะห้าตัว

โดยการกำหนดผลลัพธ์ของสถานะภายในอาร์เรย์ของบิต ฉันค้นหาผลลัพธ์ภายในโดยใช้เครื่องหมายเฉพาะภายในอินพุต

ดังที่ระบุไว้ในโซลูชันอื่น ๆ อักขระ 2, 3 และ 4 มีลักษณะเฉพาะระหว่างอินพุตที่เป็นไปได้ ฉันใช้งานตัวอักษร 2 และ 3 อย่างเข้มข้นซึ่งฉันใช้เพื่อเลือกบิตที่เหมาะสมภายในอาร์เรย์คำตอบของฉัน

ภายในอักขระ 2 บิตที่ 1 ถึง 4 จะระบุอินพุตอย่างชัดเจน โดยการปิดบังบิตเหล่านี้และขยับอย่างเหมาะสม [นั่นคือ "* y & 47 >> 1"] อินพุตสามารถถูกบันทึกเป็น 0, 1, 4, 7 หรือ 8 ดังนั้นสตริงคำตอบของฉันจึงมี 9 ตัวอักษร (แยกบิตที่น่าสนใจ)

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

ภายในอักขระ 3 บิต 0, 1 และ 2 ระบุอินพุตได้อย่างชัดเจน โดยการปิดบังบิตเหล่านี้ (ไม่จำเป็นต้องเปลี่ยน) [นั่นคือ "* x & 7"] อินพุตสามารถบันทึกเป็น 0, 1, 2, 3 หรือ 7 (แยกบิตที่น่าสนใจ)

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

สตริงคำตอบนั้นสามารถคำนวณได้โดยเพียงเติมบิตสำหรับอักขระที่เหมาะสม

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

ดังนั้นตั้งค่าบิตในถ่านที่ Y ชนะ

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

จากนั้นตรรกะก็คือ: ถ้าถ่านตัวที่สองเหมือนกันแล้วก็ดึงมิฉะนั้นรับ ASCII ถ่านโดยใช้ตัวละครตัวที่สองของ y และ shift bits โดยตัวที่สามของ x แล้วเพิ่มหนึ่งตัว สิ่งนี้ทำให้คำตอบ 0 สำหรับการวาด 1 สำหรับ x win และ 2 สำหรับ y win


ยินดีต้อนรับสู่ PPCG! นี่เป็นคำตอบที่ยอดเยี่ยมและคิดอย่างดี
FantaC

1

Clojure, 130 118 ไบต์

-12 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)))

ผมคิดว่าผมเป็นฉลาด แต่นี้จบลงด้วยการไร้เดียงสาเมื่อเทียบกับคำตอบอื่น ๆ บางส่วนและมากอีกต่อไป

ใช้ตัวอักษร 2 ตัวแรกของสตริงการย้ายแต่ละตัวรับรหัสถ่านและสรุป dจากนั้นก็หักจำนวนเงินที่จะได้รับ ถ้าdเป็น 0 มันคือเน็คไท (0) ถ้าอยู่ในเซตของ#{5 -16 12 -14 13 1 4 -18 2 11}p1 จะชนะ (1) มิฉะนั้น p2 จะชนะ (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)))

ในการรับ "หมายเลขเวทมนตร์" ที่กำหนดว่า P1 ชนะฉันจะวิ่ง

(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])))

ซึ่งสร้างรายการdค่าสำหรับแต่ละสถานการณ์ที่เป็นไปได้:

(["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])

จากนั้นฉันเปรียบเทียบแผนภูมิชนะกับผลลัพธ์นี้ โชคดีที่ไม่มี "การชน" นอกเหนือจาก 0

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.