Gerade oder ungerade: drei Spieler


15

Es ist ein Drei-Spieler-Spiel, mit einer Hand zu spielen.

Gleichzeitig zeigt jeder Spieler seine Hand mit 0 bis 5 ausgestreckten Fingern.

Wenn alle Spieler dieselbe Art von (gerader oder ungerader) Zahl zeigen, gibt es keinen Gewinner. Ansonsten gewinnt der Spieler, der eine andere Art zeigt, die beiden anderen.

 P l a y e r s
A      B      C       Winner

Even   Even   Even    No winner
Odd    Odd    Odd     No winner
Even   Odd    Odd     Player A
Odd    Even   Even    Player A
Even   Odd    Even    Player B
Odd    Even   Odd     Player B
Odd    Odd    Even    Player C
Even   Even   Odd     Player C

Das angeforderte Tool kann Argumente (3 numerische Argumente zwischen 0 und 5) oder STDIN (3 Werte durch Zeile, durch Leerzeichen getrennt) verwenden.

Die Eingabe muss nicht überprüft werden: Eine unregelmäßige Eingabe kann zu einer unerwarteten Ausgabe führen.

Argumente oder Werte in der Zeile werden von links nach rechts von Spieler A bis Spieler C angegeben .

Ausgang muss nur enthalten A, Boder C(aktiviert) oder die Zeichenfolgeno one (in Kleinbuchstaben, mit einem normalen Raum).

Das Tool kann nur einmal oder als Filter für alle Eingabezeilen verwendet werden.

Kürzester Code-Gewinn.


6
Könnte als [König des Hügels] interessanter sein. Spiel das Spiel.
dmckee

Ich frage mich, wie sich die Tatsache, dass wir 5 Finger haben (es sind also 3 ungerade und 2 gerade Finger möglich), auf die Gewinnstrategie auswirkt ...
Olivier Dulac

@OlivierDulac, 0 ist auch eine gerade Zahl.
Peter Taylor

In dieser Spielregel lassen sich ja die gleichen Chancen für gerade als für ungerade Zahlen (0 2 4 vs 1 3 5)
F. Hauri

@ PeterTaylor: Danke, ich habe die Frage falsch verstanden (und ich dachte nicht, dass es zählen würde).
Olivier Dulac

Antworten:


12

APL ( 34 30)

(1⍳⍨+/∘.=⍨2|⎕)⊃'ABC',⊂'no one'

Erläuterung:

  • 2|⎕: eine Eingabezeile lesen, den Mod-2 jeder Zahl nehmen (dh eine Liste angeben 1 0 1)
  • ∘.=⍨: Vergleiche jedes Element im Vektor mit jedem Element im Vektor, um eine Matrix zu erhalten
  • +/: summiere die Zeilen der Matrix und gebe für jedes Element an, wie viele Elemente es enthält. Wenn es zwei gleiche und eine unterschiedliche gab, haben wir jetzt einen Vektor wie 2 1 2den, der 1angibt, wer unterschiedlich war. Wenn sie alle gleich wären, bekommen wir 3 3 3.
  • 1⍳⍨: Finden Sie die Position des 1. Wenn 1dies nicht der Fall ist , gibt dies in diesem Fall einen Wert mehr als die Länge des Vektors zurück 4.
  • ⊃'ABC',⊂'no one': zeigt den String am angegebenen Index an.

Gute Verwendung der Array-orientierten Programmierung zur Indexberechnung.
FireFly

8

Mathematica, 45 43 42 41 Zeichen

f="no one"[A,B,C]〚Mod[Tr@#-#,2].{2,1,0}〛&

Beispiel:

f[{0 ,0, 0}]

Niemand

f[{1, 3, 5}]

Niemand

f[{2, 3, 5}]

EIN

f[{2, 3, 4}]

B


Eine andere Lösung mit 43 42 Zeichen:

f=Mod[Tr@#-#-1,2].{A,B,C}/._+__->"no one"&


4

Befunge-98, 61 50 45 Zeichen

&&&:11p+2%2*\11g+2%+:"@"+#@\#,_0"eno on">:#,_

Verwendet Fors 'geschickten Ausdruck, um noch ein paar weitere Charaktere abzuschaben. Jetzt einzeilig (dh Unefunge-kompatibel)! Liest, bis ein Spiel gewonnen ist; @am Ende für ein One-Shot-Programm hinzufügen .

Behandelt Eingabemod 2 wie bei meiner JS-Antwort als Binärzahl, verlässt sich dann auf die Suche nach AC und fällt bei Überschreitung auf 'no one' zurück (indem geprüft wird, ob das Zeichen ≥'A ist, was mir erlaubt) um Code in der Nähe als Daten zu verwenden: D).

Eine Variation, die eine Eingabezeile liest, eine Ausgabe erzeugt, eine neue Eingabezeile liest usw., bis ein Spiel entschieden ist (dh nicht "niemand"):

&2%4*&2%2*&2%++1g:" "#@-#,_0"eno on">:#,_
 CBAABC


Ich portierte dies, um nach meiner Antwort zu fischen. Ich habe dich bemerkt. +1 übrigens
Cruncher

4

APL, 30

(1+2=/2|⎕)⊃'BA'('C',⊂'no one')

Wenn ich Systemvariablen durch Konfiguration ändern darf, können 2 Zeichen abgeschnitten werden. (Insbesondere Ändern des Indexursprungs ⎕IOauf 0)

Das Entscheidende

Wenn wir alle Gewinnchancen auf die gleiche Weise darstellen und alle Gewinnchancen auf die gleiche Weise, kann eine paarweise Gleichheitsoperation alle 4 Fälle unterscheiden: 0 0für B Siege, 0 1für A Siege usw.

Erläuterung

2|⎕Nimmt Eingang und Mod 2
2=/paarweise Gleichheit
1+ Addiere 1 für die Indizierung (APL-Arrays basieren standardmäßig auf 1).

'BA'('C',⊂'no one')Verschachteltes Array
Wählt das richtige Element aus dem verschachtelten Array aus


3

C: 88 Zeichen

Leider erfordert C, wie immer, ziemlich viel unnötigen Müll. Aber dennoch, in welcher anderen Sprache kann man schreiben =**++b+**(++und es bedeutet tatsächlich etwas? Ganz einfach großartig.

main(int a,char**b){(a=**++b+**(++b+1)&1|2*(**b+**++b&1))?putchar(a+64):puts("no one");}

Übergeben Sie einfach drei Zahlen als Argumente und voilà!


Ist die genaue Reihenfolge dieser Vorstufen festgelegt? Ich dachte, es wäre nicht ... obwohl Sie sie *b[1]ohne Größenunterschied durch usw. ersetzen könnten (obwohl ein gewisser Verlust an Eleganz .. :()
FireFly

In Ruby s = "=**++b+**(++":: P im Ernst, wow, wie geht das ... wie geht das überhaupt? : O
Türklinke

@Doorknob ist sehr clever, aber wenn Sie bstattdessen die Dereferenzierung und Vorinkrementierung durch Indizierung ersetzen und die Bedingung mit einigen hübschen Ausdrucken versehen, sollten Sie in der Lage sein, dies herauszufinden. : D (Stift und Papier hilft auch, für die resultierende Wahrheitstabelle)
FireFly

3

GolfScript (31 Zeichen)

~]{1&}%.$1=!?)'no one
A
B
C'n/=

Sehr einfache Logik: Reduzieren Sie das Eingangsmodul 2 und sortieren Sie dann eine Kopie. Das mittlere Element des sortierten Arrays befindet sich in der Mehrheit. Suchen Sie daher nach einem anderen Index (und damit in der Minderheit).


3

Ruby (Funktionskörper), 42 Zeichen

Unter der Annahme , 3 numerische Argumente a, bund c:

['zCBAABCz'[a%2*4|b%2*2|c%2],'no one'].min

Ruby (Kommandozeilen-Tool), 61 Zeichen

Version 1 hat 62 Zeichen:

$><<["zCBAABCz"[$*.reduce(0){|i,n|i*2|n.to_i%2}],'no one'].min

Indem die Antwort von Darren Stone huckepack genommen wird, reduziert sich Version 2 auf 61 Zeichen:

i=0;$*.map{|n|i+=i+n.to_i%2};$><<['zCBAABCz'[i],'no one'].min

3

Rubin, 61 Zeichen

w=0
$*.map{|p|w+=w+p.to_i%2}
$><<%w(no\ one C B A)[w>3?w^7:w]

['no one',?C,?B,?A]== %w(no\ one C B A)(2 Zeichen gespeichert).
Daniero

Nett. Wendet das an. Danke!
Darren Stone

2

JavaScript (Knoten), 87 Zeichen

p=process.argv;console.log("ABC"[3-Math.min(x=p[2]%2*4+p[3]%2*2+p[4]%2,7-x)]||"no one")

Um den Ball ins Rollen zu bringen, werden drei zusätzliche Argumente erwartet. Verwendet das folgende Muster für die Eingabe / Ausgabe (steht /für "Niemand"):

  A B C  res  #
 ───────────────
  0 0 0   /   0
  0 0 1   C   1
  0 1 0   B   2
  0 1 1   A   3
  1 0 0   A   4
  1 0 1   B   5
  1 1 0   C   6
  1 1 1   /   7

2

GolfScript, 36 35 33 Zeichen

~]0\{1&\.++}/'no one
C
B
A'n/.$+=

Übernimmt die Eingabe wie von STDIN beschrieben. Sie können den Code auch online testen .


2

Perl, 84 Zeichen.

$x=oct"0b".join"",map{$_%2}<>=~/(\d)/g;print"",('no one','C','B','A')[$x>=4?7-$x:$x]
  • <>=~/(\d)/g Parst die Eingabezeile in verschiedene Ziffern
  • map{$_%2 Nimmt diese Liste und berechnet den Wert mod 2 (gerade oder ungerade)
  • oct"0b".join"", Nimmt diese Liste von Mod-Werten, fügt sie zu einem String zusammen, hängt einen Oktal-Bezeichner an und konvertiert den String in eine Zahl.

Grundsätzlich habe ich eine Wahrheitstabelle erstellt und diese dann sorgfältig neu angeordnet, sodass eine Inversionsoperation durchgeführt wurde $x == 4. Wenn ja $x >=4, haben wir die Inversion gemacht[$x>=4?7-$x:$x] der wir das Array indiziert haben('no one','C','B','A')

Es ist nicht der kürzest mögliche Code, aber es ist eigentlich kein Zeilenrauschen ... was an und für sich bemerkenswert ist.

Perl: 74 Zeichen + 3 Flags = 77, laufen mit perl -anE '(code)'

s/(\d)\s*/$1%2/eg;$x=oct"0b".$_;say"",("no one","C","B","A")[$x>3?7-$x:$x]

Dies ist eine Verbesserung, indem Sie Autosplit (das -a), sagen wir (das -E), verwenden und schließlich herausfinden, was mit dem Vergleich nicht stimmte.


Warum >=4statt einfach >3? +1 für die Tipps, die '0b'.ich vorher nicht kannte
F. Hauri

Ich habe beide im Debugger ausprobiert (> 3 und> = 4), und ich bin mir nicht sicher, warum, aber das> = 4 hat funktioniert, aber> 3 nicht. Ich kann es auch nicht zu meiner eigenen Zufriedenheit erklären
Joe

Sie scheinen in beiden Fällen einen Sondercharakter gehabt zu haben, den ich behoben habe. Außerdem zählen Flags als Zeichen.
Türklinke

2

Common Lisp, 114 106 70 Zeichen

Erstellen Sie aus den drei Werten ein Paar, das den Unterschied in der Parität zwischen benachbarten Elementen darstellt. Behandle das als eine binäre Zahl, die in die Ergebnisliste aufgenommen wird.

(defun f(a b c)(elt'(no_one c a b)(+(mod(- b c)2)(*(mod(- a b)2)2)))))

Älterer Algorithmus:

(defun f(h)(let*((o(mapcar #'oddp h))(p(position 1(mapcar(lambda(x)(count x o))o))))(if p(elt'(a b c)p)"no one")))

2

Python 2, 54

f=lambda a,b,c:[['no one','C'],'BA'][(a^b)&1][(a^c)&1]

1

Mathematica 100 94 89

f=If[(t=Tally[b=Boole@OddQ@#][[-1,2]])==1,{"A","B","C"}[[Position[b,t][[-1,1]]]],"no one"]&

Testen

f[{5, 3, 1}]
f[{2, 0, 4}]
f[{0, 1, 2}]
f[{0, 1, 3}]
f[{1, 3, 0}]

"Niemand"
"niemand"
"B"
"A"
"C"


1

Haskell, 97

main=interact$(["no one","A","B","C"]!!).(\x->min x$7-x).foldr(\y x->x*2+mod y 2)0.map read.words

1

R 67

z="no one";c("A","B","C",z,z)[match(2-sum(x<-scan()%%2),c(x,2,-1))]

Interessant! Wie könnte ich das testen? Was muss ich rennen (vielleicht ein Shebang?)
F. Hauri

Sie müssen eine interaktive R-Sitzung starten (z. B. /usr/bin/R) und dann den obigen Code eingeben. scan()wird Sie zur Eingabe auffordern: Ein Beispiel wäre die Eingabe, 1[space]3[space]5[space][enter][enter]und Sie werden die entsprechende Ausgabe (hier, no one) auf dem Bildschirm sehen. Sie können R hier herunterladen: cran.r-project.org/mirrors.html
flodel

1

C 85 Zeichen

main(int j,char**p){puts("C\0A\0B\0no one"+((**++p&1)*2+(**++p&1)^(**++p&1?0:3))*2);}

Nicht so kurz wie meine Ruby-Antwort, aber ich bin zufrieden damit, wenn man die mainCruft bedenkt.


1

Fisch - 41

:&+2%2*$&+2%+:"@"+!;$!o :?#"eno on"!;ooo<

Hat die Antwort von FireFly gestohlen und auf Fisch portiert, da wir durch die Verwendung von Registern in Fischen einige Zeichen abschneiden können. Verlor ein paar Zeichen, weil der Operator if nicht horizontal war.

Dadurch werden Parameter durch Argumente übernommen.

python fish.py evenodd.fish -v 2 2 2  
no one
python fish.py evenodd.fish -v 2 3 2  
B
python fish.py evenodd.fish -v 2 3 3  
A
python fish.py evenodd.fish -v 3 3 4  
C

Ooooooooooo schön!
F. Hauri

Hm, Fisch, was? Hast du ein Trampolin? Wenn ja, könnten Sie vielleicht (das Äquivalent von) #@...<am Ende verwenden, um ein Zeichen zu speichern. Oh, und Ihr aktueller Code sieht für mich aus wie 42 Zeichen. Verringern Sie also Ihre Zeichenanzahl. :)
FireFly

@FireFly danke! Das hat einen Charakter gerettet, und Sie haben Recht, ich war um eins überzählt. Mein Texteditor sagte am Ende "col 43". Aber natürlich zeigt der Cursor in einer leeren Zeile "col 1".
Cruncher

1

Smalltalk, 128 Zeichen

[:c|o:=c collect:[:e|e odd].k:=o collect:[:e|o occurrencesOf:e].u:=k indexOf:1.^(u>0)ifTrue:[#($a $b $c)at:u]ifFalse:['no one']]

sende value:mit einer sammlung


1

JavaScript (ES6) / CoffeeScript, 50 Byte

Verwendet die Wahrheitstabelle gemäß der Antwort von Firefly, geht aber beim Zugriff auf Charaktere direkter vor:

f=(a,b,c)=>'CBAABC'[(a%2*4+b%2*2+c%2)-1]||'no one' // JavaScript
f=(a,b,c)->'CBAABC'[(a%2*4+b%2*2+c%2)-1]||'no one'  # CoffeeScript

Demo

// Translated into ES5 for browser compatibility
f=function(a,b,c){return'CBAABC'[(a%2*4+b%2*2+c%2)-1]||'no one'}

//f=(a,b,c)=>'CBAABC'[(a%2*4+b%2*2+c%2)-1]||'no one'

for(i=6;i--;)
  for(j=6;j--;)
    for(k=6;k--;)
      O.innerHTML += i + ', ' + j + ', ' + k + ' => ' + f(i,j,k) + "\n"
<pre id=O></pre>


0

Python 3, 115

l=[int(x)%2for x in input().split()];0if[print("ABC"[i])for i,x in enumerate(l)if l.count(x)%2]else print("no one")

0

Python 3, 114

r=[0,3,2,1,1,2,3,0][int("".join(map(str,(int(x)%2for x in input().split()))),2)];print("ABC"[r-1]if r else"no one")

0

Zwei verschiedene Methoden in zwei verschiedenen Sprachen + Variationen -> 6 Antworten

Für diese Operation gibt es im Wesentlichen zwei Möglichkeiten:

  • array based: Erstellt eine dreistellige Binärzahl als Antwort aus einem Array
  • count based: Zähle gerade und ungerade und schau, ob es eine gibt count == 1

Perl 71 (Array-basiert + Variation)

s/(.)\s*/$1&1/eg;$==oct"0b".$_;$==$=>3?7-$=:$=;say$=?chr 68-$=:"no one"

Eines meiner kürzesten perl:

  • s/(.)\s*/$1&1/eg;transformiere einen String wie 1 2 3in101
  • $==oct"0b".$_; transformiere binär in okt (wie dez, unter 8)
  • $==$=>3?7-$=:$=;wenn > 3oper 7-. (Von dort no one== 0)
  • say$=?chr 68-$=:"no one"wenn nicht 0, drucke char von value, sonst drucke no one.

Perl 71 (Array-basiert)

s/(.)\s*/$1&1/eg;$==oct"0b".$_;say@{["no one",qw{A B C}]}[$=>3?7-$=:$=]

etwas anders im Druckschritt: Die Ausgabe basiert auf einem 'Array' .

Perl 81 (zählbasiert)

$c=A;map{$a[$_%2]=$c++;$b[$_%2]++}split;say$b[0]==1?$a[0]:$b[0]==2?$a[1]:"no one"

Andere Bedeutung:

  • $c=A Initialisieren Sie einen Zähler c mit A.
  • map{$a[$_%2]=$c++;$b[$_%2]++}splitZähler b zählen gerade und ungerade, ein einziger Speicher, welcher
  • say$b[0]==1?$a[0]: wenn sogar counter == 1? drucken Sie auch sogar Spieler.
  • $b[0]==2?$a[1]:wenn auch Zähler == 2? auch ungerade Spieler drucken .
  • :"no one"sonst drucken no one.

Bash 85 (Array-basiert)

c=$((($1%2)<<2|($2&1)*2+($3%2)));((c>3))&&c=$((7-c));o=("no one" C B A);echo ${o[c]}

Dies basiert auf meiner zweiten Perl-Version:

  • c=$((($1%2)<<2|($2&1)*2+($3%2))) mache den Index pos.
    • $ 1% 2 transformiere das erste Argument in binär mit mod
    • $ 2 & 1 transformieren das zweite Argument in binär mit and
    • << 2 Verschiebung nach links ist dasselbe wie*4
    • * 2 multiplizieren mit 2 ist dasselbe wie <<1.
  • ((c>3))&&c=$((7-c)) wenn c> = 4, dann ist c = 7-c.
  • o=() Deklarieren Sie ein Array
  • echo ${o[c]} basierend auf Array

Bash 133 (zählbasiert)

a[$1&1]=A;a[$2&1]=B;a[$3&1]=C;((b[$1&1]++));((b[$2&1]++));((b[$3&1]++))
case $b in 1)echo ${a[0]};;2)echo ${a[1]};;*)echo no one;esac
  • a[$1&1]=A;a[$2&1]=B;a[$3&1]=CSpieler in Variable a [gerade] und a [ungerade] speichern
  • ((b[$1&1]++));((b[$2&1]++));((b[$3&1]++))zählen gerade / ungerade zu b.
  • case $b in 1) echo ${a[0]} falls gerade Zähler == 1 gerade Spieler drucken
  • 2)echo ${a[1]};; case even counter == 2 drucke ungeraden Player
  • *)echo no one;esacsonst drucken no one.

Bash 133 (zählbasiert)

a[$1&1]=A;a[$2&1]=B;a[$3&1]=C;((b[$1&1]++));((b[$2&1]++));((b[$3&1]++))
((b==1))&&echo ${a[0]}||(((b==2))&&echo ${a[1]}||echo no one)

Gleiche Version, mit der Bedingung und Befehlsgruppe von bash anstelle von case ... esac


0

Game Maker Language, 116

Meine neue Antwort basiert stark auf der Formel von FireFly:

a[1]="no one"a[2]='A'a[3]='B'a[4]='C'return a[(3-min(b=argument0 mod 2*4+argument1 mod 2*2+argument2 mod 2,7-b)||1)]

Der alte Code wurde mit nicht initialisierten Variablen mit 0 bis 183 Zeichen kompiliert :

a=argument0 mod 2b=argument1 mod 2c=argument2 mod 2if((a&&b&&c)||(!a&&!b&&!c))return "no one" else{if((a&&b)||(!a&&!b))return "C" else{if((a&&c)||(!a&&!c))return "B" else return "A"}}

Edit # 1 - Ganz anderer Code


Interessant!? Ich habe diese Sprache vorher nicht gekannt! Da diese Sprache jedoch die Verwendung von Arrays zulässt, scheint dieser Code für diesen Job nicht der kleinstmögliche zu sein.
F. Hauri

@ F.Hauri Ja, ich versuche Arrays zu verwenden, um es kürzer zu machen.
Timtech

0

Clojure, 116

(fn[& h](let[a(map #(bit-and % 1)h)](["no one"\A\B\C](+(.indexOf(map(fn[x](reduce +(map #(if(= x %)1 0)a)))a)1)1))))

0

vba, 116

Function z(q,r,s)
a="A":b="B":c="C":d="no one"
z=Array(d,c,b,a,a,b,c,d)((q And 1)*4+(r And 1)*2+(s And 1))
End Function

Rufen Sie mit auf ?z(1,2,3)oder weisen Sie einer Variablen mit zu q=z(1,2,3), oder verwenden Sie sie sogar als UDF in Excel und verwenden Sie sie =z(1,2,3)in Ihrer Excel-Formel


0

Python 3, 80 Zeichen

r=int(input().replace(' ',''),2)
print(['no one','C','B','A'][7-r if r>3 else r])

Hinweis: Die Eingabe muss "1" [ungerade] oder "0" [gerade] sein. Beispielsweise:

> 1 1 0
C
> 1 1 1
no one

Die Herausforderung erfordert, dass die Eingabe "durch Leerzeichen getrennt" ist. Vielleicht gibt es eine Möglichkeit, effektiv Golf zu spielen, splitund joinso können Sie Ihre (sehr kluge) int(...input...)Idee immer noch nutzen . ?
Darren Stone

Sie könnten das entfernen, was '0b'+ich denke, zumindest sieht es für mich überflüssig aus und int(input(),2)scheint nur in einer REPL zu funktionieren.
FireFly

@ DarrenStone Ich habe stattdessen eine Zeichenfolge zum Ersetzen verwendet, siehe Bearbeiten
Dhara

@FireFly Danke, Sie haben Recht, ich habe meine Antwort bearbeitet. Ich habe den Code zuerst mit Python 2 getestet, wo die '0b' benötigt wurde.
Dhara

Die Herausforderung erfordert auch die Eingabe von Zahlen von 0 bis 5.
Peter Taylor

0

Java, 226 Zeichen

void func(int a, int b, int c){
    a = a%2;
    b = b%2;
    c = c%2;
    String out = "B";
    if((a+b+c)==0 || (a+b+c)==3)
        out = "no one";
    else if(a==b)
        out = "C";
    else if(b==c)
        out = "A";
    System.out.println(out);
}

0

C 101 96

C, wahrscheinlich das trivialste Beispiel (einige ternäre Operationen):

main(int v,char** c){(v=c[1]==c[2]?c[1]==c[3]?0:3:c[1]==c[3]?2:1)?puts("no one"):putchar(v+64);}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.