ร็อค, กระดาษ, กรรไกร, จิ้งจก, สป็อค [ปิด]


16

สร้างฟังก์ชั่นที่จะรับสองสายเป็นอินพุตและส่งกลับผลลัพธ์เดียวสำหรับผลลัพธ์ คำตอบที่ได้รับความนิยมมากที่สุดชนะ

กฎของ Rock-paper-scissors-lizard-Spock คือ:

  • กรรไกรตัดกระดาษ
  • กระดาษบังหิน
  • หินทับจิ้งจก
  • Lizard พิษ Spock
  • สป็อคแตกกรรไกร
  • กรรไกรประหารจิ้งจก
  • จิ้งจกกินกระดาษ
  • กระดาษไม่รองรับสป็อค
  • สป็อคระเหยหิน
  • กรรไกรหินแตก

เอาต์พุตสำหรับทุกกรณีอินพุตที่เป็นไปได้คือ:

winner('Scissors', 'Paper') -> 'Scissors cut Paper'
winner('Scissors', 'Rock') -> 'Rock breaks Scissors'
winner('Scissors', 'Spock') -> 'Spock smashes Scissors'
winner('Scissors', 'Lizard') -> 'Scissors decapitate Lizard'
winner('Scissors', 'Scissors') -> 'Scissors tie Scissors'
winner('Paper', 'Rock') -> 'Paper covers Rock'
winner('Paper', 'Spock') -> 'Paper disproves Spock'
winner('Paper', 'Lizard') -> 'Lizard eats Paper'
winner('Paper', 'Scissors') -> 'Scissors cut Paper'
winner('Paper', 'Paper') -> 'Paper ties Paper'
winner('Rock', 'Spock') -> 'Spock vaporizes Rock'
winner('Rock', 'Lizard') -> 'Rock crushes Lizard'
winner('Rock', 'Scissors') -> 'Rock breaks Scissors'
winner('Rock', 'Paper') -> 'Paper covers Rock'
winner('Rock', 'Rock') -> 'Rock ties Rock'
winner('Lizard', 'Rock') -> 'Rock crushes Lizard'
winner('Lizard', 'Spock') -> 'Lizard poisons Spock'
winner('Lizard', 'Scissors') -> 'Scissors decapitate Lizard'
winner('Lizard', 'Paper') -> 'Lizard eats Paper'
winner('Lizard', 'Lizard') -> 'Lizard ties Lizard'
winner('Spock', 'Rock') -> 'Spock vaporizes Rock'
winner('Spock', 'Lizard') -> 'Lizard poisons Spock'
winner('Spock', 'Scissors') -> 'Spock smashes Scissors'
winner('Spock', 'Paper') -> 'Paper disproves Spock'
winner('Spock', 'Spock') -> 'Spock ties Spock'

ความท้าทายเพิ่มเติมที่แนะนำโดย @Sean Cheshire: อนุญาตรายการที่กำหนดเองเช่นจากไซต์นี้ ด้วยรายการ n-item ไอเท็มจะหายไปก่อนหน้า (n-1) / 2 และชนะมากกว่า (n-1) / 2 ต่อไปนี้


7
การสร้างตารางการค้นหา 25 องค์ประกอบไม่ได้ท้าทายและได้รับความนิยมไม่ได้เป็นรหัสความท้าทาย
Peter Taylor

6
และเมื่อฉันบอกว่าการเป็นที่นิยมไม่ใช่การท้าทายรหัส : คำอธิบายของแท็กนั้นเริ่มต้นการท้าทายรหัสคือการแข่งขันเพื่อหาวิธีที่สร้างสรรค์ในการแก้ปริศนาการเขียนโปรแกรมสำหรับเกณฑ์วัตถุประสงค์นอกเหนือจากขนาดรหัส "คำตอบที่ได้รับความนิยมมากที่สุดชนะ" ไม่ใช่เกณฑ์วัตถุประสงค์: คุณไม่สามารถให้คำตอบกับใครบางคนสองคนและถามพวกเขาซึ่งเป็นที่นิยมมากที่สุด
Peter Taylor

1
@PeterTaylor, dansalmo ถูกต้องตราบใดที่ตารางการค้นหาอยู่ในลูป: นี่เป็นทฤษฎีบทที่มีชื่อเสียงของ Conway: en.wikipedia.org/wiki/FRACTRAN
บูธโดย

1
@dansalmo ความท้าทายที่คุณเชื่อมโยงถูกสร้างขึ้นก่อนที่จะมีแท็กประกวดความนิยม
primo

1
คำแนะนำในการเพิ่มความท้าทาย - อนุญาตรายการที่กำหนดเองเช่นรายการจากไซต์นี้ที่มีมากถึง 101 รายการ ด้วยรายการ n-item ไอเท็มจะแพ้ (n-1) / 2 ก่อนหน้าและชนะเหนือ (n-1) / 2 follwing
SeanC

คำตอบ:


13

APL

vs←{
    n←'Scissors' 'Paper' 'Rock' 'Lizard' 'Spock'
    x←n⍳⊂⍺ ⋄ y←n⍳⊂⍵ ⋄ X←⍺ ⋄ Y←⍵ ⋄ r←{X,⍵,⊂Y}
    x=y:     r (-x=0)↓'ties'
    y=5|1+x: r x⌷'cut' 'covers' 'crushes' 'poisons' 'smashes'
    y=5|3+x: r x⌷'decapitate' 'disproves' 'breaks' 'eats' 'vaporizes'
    ⍵∇⍺
}

เอาต์พุตตรงตามที่ต้องการในทุกกรณีรวมถึงเน็คไท / เน็คไท ไม่มีตารางการค้นหายกเว้นคำศัพท์จริง

คุณสามารถลองได้ที่http://ngn.github.io/apl/web/

'Spock' vs 'Paper'
Paper  disproves  Spock

APL เพิ่งรู้!


+1 ไม่เคยสังเกตเห็น APL จนกระทั่งตอนนี้ ที่ชวนให้หลงใหล โครงสร้างของคุณก็เจ๋งเช่นกัน ฉันชอบบรรทัดสุดท้ายที่ดีที่สุด
dansalmo

@dansalmo ขอบคุณ :) ฉันชอบมันมาก และตอนนี้ต้องขอบคุณgithub.com/ngn/aplเรามีโอเพ่นซอร์สและล่ามพร้อมเว็บ (มานานหลายทศวรรษแล้วที่มีล่ามในเชิงพาณิชย์เท่านั้น)
Tobia

@dansalmo BTW, APL เป็นแบบที่สมบูรณ์แบบสำหรับชนิดของการทำงานการเขียนโปรแกรมที่คุณดูเหมือนจะทำในหลาม (ซึ่งผมชอบที่จะทำเช่นกัน)
Tobia

10

SED

#!/bin/sed
#expects input as 2 words, eg: scissors paper

s/^.*$/\L&/
s/$/;scissors cut paper covers rock crushes lizard poisons spock smashes scissors decapitates lizard eats paper disproves spock vaporizes rock breaks scissors/
t a
:a
s/^\(\w\+\)\s\+\(\w\+\);.*\1 \(\w\+\) \2.*$/\u\1 \3 \u\2/
s/^\(\w\+\)\s\+\(\w\+\);.*\2 \(\w\+\) \1.*$/\u\2 \3 \u\1/
t b
s/^\(\w\+\)\s\+\1;\(\1\?\(s\?\)\).*$/\u\1 tie\3 \u\1/
:b

1
นี่คือ ... โหดเหี้ยม
Wayne Conrad

4

นี่คือโซลูชันทั่วไปที่ยึดตามสตริงกฎทุกขนาด จะดำเนินการตัวพิมพ์ใหญ่ให้ถูกต้องสำหรับชื่อที่เหมาะสม "Spock" และยังอนุญาตให้กฎสำหรับการระบุ 'เสมอ' แทน 'ผูก' สำหรับวัตถุพหูพจน์

def winner(p1, p2):
    rules = ('scissors cut paper covers rock crushes lizard poisons Spock'
    ' smashes scissors decapitate lizard eats paper disproves Spock vaporizes'
    ' rock breaks scissors tie scissors'.split())

    idxs = sorted(set(i for i, x in enumerate(rules) 
                      if x.lower() in (p1.lower(), p2.lower())))
    idx = [i for i, j in zip(idxs, idxs[1:]) if j-i == 2]
    s=' '.join(rules[idx[0]:idx[0]+3] if idx 
          else (rules[idxs[0]], 'ties', rules[idxs[0]]))
    return s[0].upper()+s[1:]

ผล:

>>> winner('spock', 'paper')
'Paper disproves Spock'
>>> winner('spock', 'lizard')
'Lizard poisons Spock'
>>> winner('Paper', 'lizard')
'Lizard eats paper'
>>> winner('Paper', 'Paper')
'Paper ties paper'
>>> winner('scissors',  'scissors')
'Scissors tie scissors'    

เมื่อกำหนดrulesคุณสามารถใช้สตริงหลายบรรทัดแทนการเรียงต่อกันตามตัวอักษร วิธีนี้ช่วยให้คุณสามารถลบวงเล็บที่ซ้ำซ้อน
Bakuriu

3

หลาม

class Participant (object):
    def __str__(self): return str(type(self)).split(".")[-1].split("'")[0]
    def is_a(self, cls): return (type(self) is cls)
    def do(self, method, victim): return "%s %ss %s" % (self, method, victim)

class Rock (Participant):
        def fight(self, opponent):
                return (self.do("break", opponent)  if opponent.is_a(Scissors) else
                        self.do("crushe", opponent) if opponent.is_a(Lizard)   else
                        None)

class Paper (Participant):
        def fight(self, opponent):
                return (self.do("cover", opponent)    if opponent.is_a(Rock)  else
                        self.do("disprove", opponent) if opponent.is_a(Spock) else
                        None)

class Scissors (Participant):
        def fight(self, opponent):
                return (self.do("cut", opponent)       if opponent.is_a(Paper)  else
                        self.do("decaitate", opponent) if opponent.is_a(Lizard) else
                        None)

class Lizard (Participant):
        def fight(self, opponent):
                return (self.do("poison", opponent) if opponent.is_a(Spock) else
                        self.do("eat", opponent)    if opponent.is_a(Paper) else
                        None)

class Spock (Participant):
        def fight(self, opponent):
                return (self.do("vaporize", opponent) if opponent.is_a(Rock)     else
                        self.do("smashe", opponent)    if opponent.is_a(Scissors) else
                        None)

def winner(a, b):
    a,b = ( eval(x+"()") for x in (a,b))
    return a.fight(b) or b.fight(a) or a.do("tie", b)

กรรไกรเป็นพหูพจน์ดังนั้น "ตัดs " กระดาษและ "decaitate s " จิ้งจก "ผิด (อันสุดท้ายพลาด P เกินไป) และ" Spock smashs "ควรเป็น" แตก ";)
daniero

@daniero ขอบคุณ ฉันสังเกตเห็นปัญหาของกรรไกร แต่การแก้ไขมันทำให้สิ่งต่าง ๆ ยุ่งยาก แก้ไข "แตก" ตอนนี้
ugoren

@Daniel "กรรไกร" เป็นพหูพจน์ "กรรไกร" ก็เป็นเอกพจน์เช่นกัน ดูen.wiktionary.org/wiki/scissors
DavidC

บอบบางมาก รักมัน
kaoD

2

หลาม

def winner(p1, p2):
    actors = ['Paper', 'Scissors', 'Spock', 'Lizard', 'Rock']
    verbs = {'RoLi':'crushes', 'RoSc':'breaks', 'LiSp':'poisons',
             'LiPa':'eats', 'SpSc':'smashes', 'SpRo':'vaporizes', 
             'ScPa':'cut', 'ScLi':'decapitate', 'PaRo':'covers', 
             'PaSp':'disproves', 'ScSc':'tie'}
    p1, p2 = actors.index(p1), actors.index(p2)
    winner, loser = ((p1, p2), (p2, p1))[(1,0,1,0,1)[p1 - p2]]
    return ' '.join([actors[winner],
                     verbs.get(actors[winner][0:2] + actors[loser][0:2],
                               'ties'),
                     actors[loser]])

1
โดยวิธีการที่ "โยก" เป็นตรงกันข้ามกับ "แน่น" "ผู้แพ้" เป็นตรงกันข้ามกับ "ผู้ชนะ" และมันจะช่วยให้คุณประหยัดอักขระในรหัสของคุณ
Joe

2

Ruby, วิธีการทางคณิตศาสตร์

นักแสดงสามารถจัดเรียงในลักษณะที่นักแสดงแต่ละคน a[i]ชนะกับนักแสดงa[i+1]และแบบa[i+2]โมดูโล 5 เช่น:

%w(Scissors Lizard Paper Spock Rock)

จากนั้นสำหรับนักแสดงที่Aมีดัชนีiเราสามารถดูว่าเขาจับคู่นักแสดงBกับดัชนีjด้วยการทำอย่างไรresult = (j-i)%5: ผลลัพธ์1และ2หมายความว่านักแสดง A ชนะกับนักแสดง 1 หรือ 2 แห่งต่อหน้าเขาตามลำดับ 3และ4ในทำนองเดียวกันก็หมายความว่าเขาแพ้นักแสดงที่อยู่ข้างหลังเขาในแถวลำดับ 0หมายถึงการผูก (โปรดทราบว่าสิ่งนี้อาจขึ้นอยู่กับภาษาใน Ruby (j-i)%5 == (5+j-i)%5ด้วยเมื่อj>iใด)

ส่วนที่น่าสนใจที่สุดของรหัสของฉันคือการใช้คุณสมบัตินี้เพื่อค้นหาฟังก์ชันการเรียงลำดับของดัชนีของนักแสดงสองคน ค่าส่งคืนจะเป็น -1, 0 หรือ 1เท่าที่ควร :

winner,loser = [i,j].sort { |x,y| ((y-x)%5+1)/2-1 }

นี่คือสิ่งทั้งหมด:

def battle p1,p2
    who = %w(Scissors Lizard Paper Spock Rock)
    how = %w(cut decapitate poisons eats covers disproves smashes vaporizes crushes breaks)
    i,j = [p1,p2].map { |s| who.find_index s }

    winner,loser = [i,j].sort { |x,y| ((y-x)%5+1)/2-1 }

    method = (winner-loser)%5/2
    what = method == 0 && "ties" || how[winner*2 + method-1]

    return "#{who[winner]} #{what} #{who[loser]}"
end

2

หลาม


  def winner(p,q):
        if p==q:
           return(' '.join([p,'tie',q]))
        d = {'ca':'cut','ao':'covers','oi':'crushes','ip':'poisons','pc': 'smashes','ci':'decapitate','ia':'eats', 'ap':'disproves', 'po':'vaporizes','oc': 'breaks'}
        [a,b] = [p[1],q[1]]
        try:
           return(' '.join([p,d[a+b],q]))
        except KeyError:
           return(' '.join([q,d[b+a],p]))

ใช้พจนานุกรมหากิน


ทำได้ดีนี่. return(' '.join([p,'tie' + 's'*(p[1]!='c'),q]))จะได้รับกริยากาลให้ถูกต้อง
dansalmo

2

ค#

สมมติฐาน

ฝ่ายตรงข้ามถูกจัดเรียงในไอเท็ม n-item ที่ผู้เล่นเอาชนะผู้เล่น (n-1) / 2 ก่อนหน้าพวกเขาและแพ้ผู้เล่น (n-1) / 2 หลัง (ด้วยรายการที่มีความยาวเท่ากันผู้เล่นจะเสียผู้เล่น ((n-1) / 2 + 1))

การกระทำของผู้เล่นจะถูกจัดเรียงในอาร์เรย์ที่การกระทำอยู่ในช่วง [(indexOfPlayer * (n-1) / 2)] ถึง [(indexOfPlayer * (n-1) / 2)) + (n-2) / 2 - 1 ]

ข้อมูลเพิ่มเติม

CircularBuffer<T>เป็น wrapper รอบ ๆ อาเรย์เพื่อสร้างอาเรย์ที่สามารถกำหนดแอดเดรสได้ "อนันต์" IndexOfฟังก์ชันส่งกลับดัชนีของรายการที่อยู่ภายในขอบเขตที่แท้จริงของอาร์เรย์

ห้องเรียน

public class RockPaperScissors<T> where T : IComparable
{
    private CircularBuffer<T> players;
    private CircularBuffer<T> actions;

    private RockPaperScissors() { }

    public RockPaperScissors(T[] opponents, T[] actions)
    {
        this.players = new CircularBuffer<T>(opponents);
        this.actions = new CircularBuffer<T>(actions);
    }

    public string Battle(T a, T b)
    {
        int indexA = players.IndexOf(a);
        int indexB = players.IndexOf(b);

        if (indexA == -1 || indexB == -1)
        {
            return "A dark rift opens in the side of the arena.\n" +
                   "Out of it begins to crawl a creature of such unimaginable\n" +
                   "horror, that the spectators very minds are rendered\n" +
                   "but a mass of gibbering, grey jelly. The horrific creature\n" +
                   "wins the match by virtue of rendering all possible opponents\n" +
                   "completely incapable of conscious thought.";
        }

        int range = (players.Length - 1) / 2;

        if (indexA == indexB)
        {
            return "'Tis a tie!";
        }
        else
        {
            indexB = indexB < indexA ? indexB + players.Length : indexB;
            if (indexA + range < indexB)
            {
                // A Lost
                indexB = indexB >= players.Length ? indexB - players.Length : indexB;
                int actionIndex = indexB * range + (indexA > indexB ? indexA - indexB : (indexA + players.Length) - indexB) - 1;

                return players[indexB] + " " + actions[actionIndex] + " " + players[indexA];
            }
            else
            {
                // A Won
                int actionIndex = indexA * range + (indexB - indexA) - 1;

                return players[indexA] + " " + actions[actionIndex] + " " + players[indexB];
            }
        }
    }
}

ตัวอย่าง

string[] players = new string[] { "Scissors", "Lizard", "Paper", "Spock", "Rock" };
string[] actions = new string[] { "decapitates", "cuts", "eats", "poisons", "disproves", "covers", "vaporizes", "smashes", "breaks", "crushes" };

RockPaperScissors<string> rps = new RockPaperScissors<string>(players, actions);

foreach (string player1 in players)
{
    foreach (string player2 in players)
    {
        Console.WriteLine(rps.Battle(player1, player2));
    }
}
Console.ReadKey(true);

1

Python หนึ่งซับ

winner=lambda a,b:(
    [a+" ties "+b]+
    [x for x in 
        "Scissors cut Paper,Paper covers Rock,Rock crushes Lizard,Lizard poisons Spock,Spock smashes Scissors,Scissors decapitate Lizard,Lizard eats Paper,Paper disproves Spock,Spock vaporizes Rock,Rock break Scissors"
        .split(',') 
     if a in x and b in x])[a!=b]

เจ๋งมาก! คุณสามารถ.split(', ')และไม่ต้องติดขัดกฎร่วมกัน
dansalmo

@ dansalmo ขอบคุณ แต่ฉันไม่เห็นอันตรายใด ๆ ใน JammingTheRulesTogether แม้ว่ามันจะไม่ใช่การแข่งขันกอล์ฟ แต่ฉันคิดว่ายิ่งดีเท่าไหร่
ugoren

1

ฉันมีของเล็ก ๆ น้อย ๆ

echo "winners('Paper', 'Rock')"|sed -r ":a;s/[^ ]*'([[:alpha:]]+)'./\1/;ta;h;s/([[:alpha:]]+) ([[:alpha:]]+)/\2 \1/;G"|awk '{while(getline line<"rules"){split(line,a," ");if(match(a[1],$1)&&match(a[3],$2))print line};close("rules")}' IGNORECASE=1

ที่นี่กฎคือไฟล์ที่มีกฎทั้งหมดที่ได้รับ


0

หลาม

แรงบันดาลใจจากรหัส APL ของ @ Tobia

def winner(p1, p2):
  x,y = map(lambda s:'  scparolisp'.find(s.lower())/2, (p1[:2], p2[:2]))
  v = (' cut covers crushes poisons smashes'.split(' ')[x*(y in (x+1, x-4))] or
       ' decapitate disproves breaks eats vaporizes'.split(' ')[x*(y in (x+3, x-2))])
  return ' '.join((p1.capitalize(), v or 'tie'+'s'*(x!=1), p2)) if v or p1==p2 \
    else winner(p2, p1)

ผล:

>>> winner('Spock', 'paper')
'Paper disproves Spock'
>>> winner('Spock', 'lizard')
'Lizard poisons Spock'
>>> winner('paper', 'lizard')
'Lizard eats paper'
>>> winner('paper', 'paper')
'Paper ties paper'
>>> winner('scissors',  'scissors')
'Scissors tie scissors'    

0

C ++

#include <stdio.h>
#include <string>
#include <map>
using namespace std ;
map<string,int> type = { {"Scissors",0},{"Paper",1},{"Rock",2},{"Lizard",3},{"Spock",4} };
map<pair<int,int>, string> joiner = {
  {{0,1}, " cuts "},{{0,3}, " decapitates "}, {{1,2}, " covers "},{{1,4}, " disproves "},
  {{2,3}, " crushes "},{{2,0}, " crushes "},  {{3,4}, " poisons "},{{3,1}, " eats "},
  {{4,0}, " smashes "},{{4,2}, " vaporizes "},
} ;
// return 0 if first loses, return 1 if 2nd wins
int winner( pair<int,int> p ) {
  return (p.first+1)%5!=p.second && (p.first+3)%5!=p.second ;
}
string winner( string sa, string sb ) {
  pair<int,int> pa = {type[sa],type[sb]};
  int w = winner( pa ) ;
  if( w )  swap(pa.first,pa.second), swap(sa,sb) ;
  return sa+(pa.first==pa.second?" Ties ":joiner[pa])+sb ;
}

การทดสอบนิดหน่อย

int main(int argc, const char * argv[])
{
  for( pair<const string&, int> a : type )
    for( pair<const string&, int> b : type )
      puts( winner( a.first, b.first ).c_str() ) ;
}

0

จาวาสคริ

function winner(c1,c2){
    var c = ["Scissors", "Paper", "Rock", "Lizard", "Spock"];
    var method={
        1:["cut", "covers", "crushes", "poisons", "smashes"],
        2:["decapitate", "disproves", "breaks", "eats", "vaporizes"]};
    //Initial hypothesis: first argument wins
    var win = [c.indexOf(c1),c.indexOf(c2)];
    //Check for equality
    var diff = win[0] - win[1];
    if(diff === 0){
        return c1 + ((win[0]===0)?" tie ":" ties ") + c2;
    }
    //If s is -1 we'll swap the order of win[] array
    var s = (diff>0)?1:-1;
    diff = Math.abs(diff);
    if(diff >2){
        diff = 5-diff;
        s= s * -1;
    }
    s=(diff==1)?s*-1:s;
    if(s === -1){
        win = [win[1],win[0]];
    }
    return c[win[0]] + " " + method[diff][win[0]] + " " + c[win[1]];
}

0

จาวาสคริ

ฉันเห็นว่านี่ไม่ใช่การแข่งขันกอล์ฟ แต่ฉันเล่นซอกับปริศนานี้อยู่พักหนึ่งก่อนจะพบกระทู้นี้ดังนั้นนี่จะไป

นี่คือเวอร์ชั่น js (มาตรฐาน) ใน 278 ตัวอักษร:

function winner(a,b){var c={rock:0,paper:1,scissors:2,spock:3,lizard:4},d="crushe,crushe,cover,disprove,cut,decapitate,smashe,vaporize,poison,eat".split(","),i=c[a],j=c[b],I=i==(j+3)%5;return i^j?i==(j+1)%5||I?a+" "+d[i*2+I]+"s "+b:b+" "+d[j*2+(j==(i+3)%5)]+"s "+a:a+" ties "+b}

หรืออย่างใดอย่างหนึ่งที่ใช้คุณสมบัติ E6 (น่าจะใช้ได้กับ Firefox เท่านั้น) 259 ตัวอักษร:

winner=(a,b,c={rock:0,paper:1,scissors:2,spock:3,lizard:4},d="crushe,crushe,cover,disprove,cut,decapitate,smashe,vaporize,poison,eat".split(","),i=c[a],j=c[b],I=i==(j+3)%5)=>i^j?i==(j+1)%5||I?a+" "+d[i*2+I]+"s "+b:b+" "+d[j*2+(j==(i+3)%5)]+"s "+a:a+" ties "+b
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.