Taş, Kağıt, Makas, Kertenkele, Spock [kapalı]


16

İki dizeyi girdi olarak alacak ve sonuç için tek bir çıktı döndürecek bir işlev oluşturun. En popüler cevap kazanır.

Taş-kağıt-makas-kertenkele-Spock kuralları şunlardır:

  • Makas kağıt kesme
  • Kağıt kaya kapakları
  • Kaya kertenkele eziyor
  • Kertenkele zehirleri Spock
  • Spock makas parçaladı
  • Makas başını kesmek kertenkele
  • Kertenkele kağıt yiyor
  • Kağıt Spock'ı reddetti
  • Spock kayayı buharlaştırır
  • Kaya makasları tatili

Olası her giriş durumu için çıktı:

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 tarafından önerilen ekstra zorluk: Bu siteden olanlar gibi özel listelere izin verin. N-madde listesiyle, öğe önceki (n-1) / 2'ye kaybeder ve aşağıdaki (n-1) / 2 değerini kazanır


7
25 öğeli bir arama tablosu oluşturmak zor değildir ve popüler olmak bir kod zorluğu değildir .
Peter Taylor

6
Ve popüler olmanın bir kod meydan okuması olmadığını söylediğimde : bu etiketin açıklaması başlıyor Bir kod meydan okuması, kod boyutu dışında objektif bir kriter için bir programlama bulmacasını çözmenin yaratıcı yolları için bir yarışmadır. "En popüler cevap kazançları" nesnel bir kriter değildir: birine iki cevap metnini veremez ve onlara en popüler olanı soramazsınız.
Peter Taylor

1
@PeterTaylor, dansalmo, arama tablosu bir döngüde olduğu sürece haklı: Bu, Conway'in ünlü bir teoremi: en.wikipedia.org/wiki/FRACTRAN
boothby

1
@dansalmo Bağlantı kurduğunuz zorluk popülerlik-yarışma etiketinin varlığından önce oluşturuldu .
primo

1
Meydan okumaya eklenecek bir öneri - Şunun gibi özel listelere izin ver: Bu siteden 101 öğeye kadar . N-madde listesiyle, öğe önceki (n-1) / 2'ye kaybeder ve (n-1) / 2 follwing'i
kazanır

Yanıtlar:


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'
    ⍵∇⍺
}

Kravat / kravat dahil tüm durumlarda tam olarak gerektiği gibi çıktı alın. Gerçek kelimeler dışında arama tablosu yok.

Http://ngn.github.io/apl/web/ adresinden deneyebilirsiniz.

'Spock' vs 'Paper'
Paper  disproves  Spock

APL biliyor!


+1, Şimdiye kadar APL'yi hiç farketmedim. Büyüleyici. Yapınız da havalı. Son çizgiyi en çok seviyorum.
dansalmo

@dansalmo Teşekkürler :) Çok beğendim. Ve şimdi github.com/ngn/apl sayesinde açık kaynak kodlu ve web'de hazır bir tercümanımız var (onlarca yıldır sadece ticari tercümanlar vardı)
Tobia

@dansalmo btw, APL, Python'da yaptığınız gibi fonksiyonel kodlama için mükemmel bir seçimdir (ben de yapmak isterim)
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
Bu ... şeytani.
Wayne Conrad

4

İşte herhangi bir boyuttaki kural dizesine dayanan genel bir çözüm. "Spock" adı için doğru büyük harf kullanımını gerçekleştirir ve ayrıca çoğul nesneler için 'bağlar' yerine 'bağlantı' belirtmek için kurallara izin verir.

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:]

Sonuçlar:

>>> 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'    

Tanımlarken rulesyerine değişmez birleştirme bir çok satırlı dize kullanabilirsiniz. Bu, gereksiz parantezleri kaldırmanıza izin verir.
Bakuriu

3

piton

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)

Makas çoğul, bu yüzden "kesim s " kağıt ve "deka s " kertenkele "yanlış (sonuncusu da bir P özlüyor) Ve" Spock şut "olmalıdır"
şut

@daniero, teşekkürler. Makas problemini fark ettim, ama düzeltmek işleri zorlaştırıyor. Şimdi "parçalamak" gideriliyor.
ugoren

@ Daniel "Makas" çoğuldur. "Makas" da tekildir. Bkz. En.wiktionary.org/wiki/scissors
DavidC

Çok ince. Sevdim.
kaoD

2

piton

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
Bu arada, "gevşek", "sıkı" tersidir. "Kaybeden", "kazanan" ın tam tersidir. Ve size kodunuzda birkaç karakter kazandıracak.
Joe

2

Ruby, aritmetik yaklaşım

Aktörler, her aktörün a[i]aktörlere a[i+1]ve a[i+2]modulo 5'e karşı kazanacağı şekilde bir dizi halinde düzenlenebilir :

%w(Scissors Lizard Paper Spock Rock)

Sonra, bir aktör için Aindeksi ibiz onun agains aktör maçları nasıl görebilirsiniz Bindeksi ile jyaparak result = (j-i)%5: Sonucu 1ve 2araçlar bu bir aktör 1 veya sırasıyla önünde 2 basamak karşı aktör A kazandı; 3ve 4benzer şekilde dizide arkasındaki bir aktöre karşı kaybettiği anlamına gelir. 0kravat anlamına gelir. (Bunun dile bağlı olabileceğini unutmayın; Ruby'de (j-i)%5 == (5+j-i)%5de ne zaman j>i.)

Kodumun en ilginç kısmı, bu özelliğin, iki aktörün endekslerinin bir sıralama işlevini bulmak için kullanılmasıdır. Dönüş değeri olması gerektiği gibi -1, 0 veya 1 olacaktır :

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

İşte her şey:

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

piton


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

Zor bir sözlük kullanma.


Güzel. return(' '.join([p,'tie' + 's'*(p[1]!='c'),q]))fiil zamanını doğru alacaktır.
dansalmo

2

C #

Varsayımlar

Rakipler, oyuncuların önlerindeki (n-1) / 2 oyuncuları yendikleri ve arkalarındaki (n-1) / 2 oyuncularına yenildikleri bir n-eşya dizisi halinde düzenlenir. (Eşit uzunluk listelerinde oyuncu arkalarındaki ((n-1) / 2 + 1) oyunculara kaybeder)

Oynatıcı eylemleri, [(indexOfPlayer * (n-1) / 2)] - [(indexOfPlayer * (n-1) / 2)) + (n-2) / 2 - 1 aralığındaki eylemlerin düzenlendiği bir dizide düzenlenir ].

İlave bilgi

CircularBuffer<T>"sonsuz" adreslenebilir bir dizi oluşturmak için bir dizinin etrafındaki sarıcıdır. IndexOfFonksiyon dizinin gerçek sınırları içinde bir öğenin dizinini döndürür.

Sınıf

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];
            }
        }
    }
}

Misal

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, tek astarlı

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]

Çok havalı! Sen edebilir .split(', ')ve birlikte, reçel, kurallara sahip değildir.
dansalmo

@dansalmo, Teşekkürler, Ama JammingTheRulesTogether'da hiçbir zarar görmüyorum. Golf yarışması olmasa da, ne kadar kısa olursa o kadar iyi olur.
ugoren

1

Geldiğim küçük bir şey:

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

Burada kurallar, verilen tüm kuralları içeren dosyadır.


0

piton

@ Tobia'nın APL kodundan esinlenilmiştir.

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)

Sonuçlar:

>>> 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 ;
}

Biraz test

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

JavaScript

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

JavaScript

Bunun bir golf yarışması olmadığını görüyorum, ama bu konuyu bulmadan önce bir süredir bu bulmacayla uğraşıyordum, işte gidiyor.

İşte 278 karakterlik bir (standart) js sürümü:

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}

Veya 259 karakterde E6 özelliklerini kullanan (muhtemelen yalnızca Firefox'ta çalışır):

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.