誰がロック、ペーパー、はさみ、トカゲ、スポックのゲームに勝ちますか?


24

このゲームに関しては、いくつかの質問がありますここコンテストもあります。しかし、これらの課題とコンテストにはすべて、ゲームの勝者を自動的に決定する方法が必要だと思います。そう:

チャレンジ

["rock", "paper", "scissors", "lizard", "spock"]プレーヤー1とプレーヤー2の選択を表す範囲内の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

制限事項

  • 入力は、指定された範囲内の文字列のペアになります(他の文字列は使用できません)。言及された値のいずれかを表す限り、必要に応じてcharの配列を使用できます。
  • 選択した大文字小文字がすべての入力で同じである限り、入力文字列に小文字、大文字("ROCK")またはキャメルケース("Rock")を使用するかどうかを選択できます。
  • 出力は、勝者を決定する3つの値になります。これは、答えが一貫している限り、任意の値にすることができます。例:1最初の入力が勝った2場合、2番目の入力が勝った0場合、同点の場合。またはA、最初の入力が勝ったB場合、2番目の入力が勝った<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

これはサンドボックスから来ます。
チャーリー


リンクされた質問の複製として閉じました。これは、同じ質問に2つの新しい値があり、IOがわずかに異なるためです。
小麦ウィザード

4
@WheatWizardは、入力のわずかな変化が非常に異なる出力を生成する場合があります。質問は非常に似ているかもしれませんが、2つの新しい値は考慮すべきケースを増やすので、ここで使用されるアルゴリズムは、人々が再考するのに十分なほど異なります(cakeトリックの答えを参照)。
チャーリー

4
私は同意し、再開することに投票しました。
GB

回答:


25

Pythonの368の 50 48バイト

編集:ニールからの3つのトリックとミスターXcoderからの2つのおかげで

各入力文字列には個別の4番目の文字があるため、それを使用して区別します。サイクル内の要素(はさみ、紙、岩、トカゲ、スポック)を配置すると、各要素はその直後に要素を打ち、要素3は周期的に右にスポットします。したがって、サイクル内の入力の位置を減算します。その数が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
ミスターXcoder

1
48バイト:オンラインでお試しください!(あなたが必要としないp"chaoi"で十分に)
ミスターXcoder

14

JavaScript(ES6)、56バイト

カリー化構文の入力を受け取ります(a)(b)0Aが勝った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

2つの入力abが与えられた場合、次のステートメントを考慮します。

  1. 我々は持っているん> bは?(辞書順)
  2. bがゲームに勝ちますか?
  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、つまり10進数で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の答えへの私のゴルフのポート。注:このスニペットは、数値の結果を少し判読不能なものにデコードします。編集:@Arnauldのおかげで1バイト保存されました。@ovsのおかげで4バイト節約されました。


うわ@ovs、私は... WhatToDoの答え十分に懸命にポート私のゴルフをしませんでした
ニール

3

ルビー、36バイト

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

01番目のプレイヤーが勝った1場合、2番目のプレイヤーが勝った場合、および2引き分けに対して返します。

user507295の回答に基づきますが、数式を使用してハッシュを実行します。a.sumは、文字列amod のすべてのASCIIコードの合計であり1<<16、基本的なチェックサムとして意図されています。次のコードを使用してハッシュが見つかりました。

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

これjにより、小文字に適切なハッシュを与える2つの値、つまり88と80が生成され、両方とも降順のシーケンスを提供しました[3,2,1,0,4](または[4,3,2,1,0]、spockが先頭まで循環する場合)。

他の回答で説明したように、上記のシーケンスの連続した要素に対して5を法とする定数差を与えるハッシュは、(h[a]-h[b])%5式を機能させるために必要です。各要素は、右の要素1または3の場所に勝ち、右の要素2または4の場所に負けます。

オンラインでお試しください!


3

C、53バイト

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

この問題をステートマシンとして扱いました。ステートマシンには、2つ、5つのステート入力によって定義される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にビットを設定する

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

次に、ロジックは単純です。2番目の文字が同じ場合は描画し、そうでない場合は、yの2番目の文字に基づいてascii charを取得し、xの3番目の文字だけビットをシフトして1を追加します。これにより、答えはドローで0、xで1、yで2になります。


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ます。d0の場合、同点(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.