15
\$\begingroup\$

It's a three players game, play with one hand.

At same time, each player show his hand with 0 to 5 fingers extended.

If all player show same kind of (even or odd) number, there is no winner. But else, the player showing different kind the two other win.

 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

The requested tool could use arguments (3 arguments as numeric between 0 and 5) or STDIN (3 values by line, separated by spaces).

There is no need to check input: Irregular input could produce unexpected output.

Arguments or values on line is given from left to right, from player A to player C.

Output must only contain A, B or C (capitalized) or the string no one (in lower case, with a regular space).

Tool may work only once or as a filter on all input lines.

Shortest code win.

\$\endgroup\$
  • 6
    \$\begingroup\$ Might be more interesting as a [king-of-the-hill]. Play the game. \$\endgroup\$ – dmckee Dec 1 '13 at 1:49
  • \$\begingroup\$ I wonder how the fact we have 5 fingers (so there are 3 odd and 2 even numbers of fingers possible) affects the winning strategy... \$\endgroup\$ – Olivier Dulac Dec 2 '13 at 11:16
  • \$\begingroup\$ @OlivierDulac, 0 is also an even number. \$\endgroup\$ – Peter Taylor Dec 2 '13 at 12:25
  • \$\begingroup\$ In this game rule yes, this let same chances for even than for odd numbers (0 2 4 vs 1 3 5) \$\endgroup\$ – F. Hauri Dec 2 '13 at 12:38
  • \$\begingroup\$ @PeterTaylor: thanks, I misread the question (and I didn't think it would count). \$\endgroup\$ – Olivier Dulac Dec 2 '13 at 13:04

30 Answers 30

12
\$\begingroup\$

APL (34 30)

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

Explanation:

  • 2|⎕: read a line of input, take the mod-2 of each number (giving a list, i.e. 1 0 1)
  • ∘.=⍨: compare each element in the vector to each element in the vector, giving a matrix
  • +/: sum the rows of the matrix, giving for each element how many elements it was equal to. If there were two the same and one different, we now have a vector like 2 1 2 where the 1 denotes who was different. If they were all the same, we get 3 3 3.
  • 1⍳⍨: find the position of the 1. If there is no 1, this returns one more than the length of the vector, in this case 4.
  • ⊃'ABC',⊂'no one': display the string at the given index.
\$\endgroup\$
  • \$\begingroup\$ Nice, good use of array-oriented programming to compute the index. \$\endgroup\$ – FireFly Nov 30 '13 at 23:54
8
\$\begingroup\$

Mathematica, 45 43 42 41 chars

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

Example:

f[{0 ,0, 0}]

no one

f[{1, 3, 5}]

no one

f[{2, 3, 5}]

A

f[{2, 3, 4}]

B


Another solution with 43 42 chars:

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

Powershell, 65

param($a,$b,$c)"@ABCCBA@"[$a%2+$b%2*2+$c%2*4]-replace"@","no one"
\$\endgroup\$
4
\$\begingroup\$

Befunge-98, 61 50 45 characters

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

Uses Fors' clever expression to shave off yet a few more characters. Now single-line (i.e. Unefunge-compatible)! Reads until a game is won; add @ at the end for a one-shot program.

Treats input mod 2 as a binary number, as with my JS answer, then relies on lookup for A-C and falls back to 'no one' if out-of-bounds (by testing if the character is ≥'A', which allows me to use nearby code as data :D).

Variation that reads a line of input, produces output, reads a new line of input, etc until a game is decided (i.e. not 'no one'):

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

\$\endgroup\$
  • \$\begingroup\$ I ported this to fish for my answer. I noted you. +1 btw \$\endgroup\$ – Cruncher Dec 2 '13 at 16:59
4
\$\begingroup\$

APL, 30

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

If I am allowed to change system variables by configuration, 2 chars can be shaved off. (Specifically, changing index origin ⎕IO to 0)

The crucial bit

If we represent all odds the same way and all evens the same way, then a pair-wise equality operation can distinguish all 4 cases: 0 0 for B wins, 0 1 for A wins, etc.

Explanation

2|⎕ Takes input and mod 2
2=/ Pair-wise equality
1+ Add 1 for indexing (APL arrays are 1-based by default)

'BA'('C',⊂'no one') Nested array
Picks out the correct element from the nested array

\$\endgroup\$
3
\$\begingroup\$

C: 88 characters

Unfortunately C, as always, requires quite a lot of unnecessary junk. But still, in which other language can one write =**++b+**(++ and it actually means something? Quite simply sublime.

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

Simply pass three numbers as arguments, and voilà!

\$\endgroup\$
  • \$\begingroup\$ Is the precise order of those preincrements specified? I thought it wasn't... although, you could replace them with *b[1] etc for no size difference (though some loss in elegance.. :( ) \$\endgroup\$ – FireFly Dec 1 '13 at 18:18
  • \$\begingroup\$ In Ruby: s = "=**++b+**(++" :P in all seriousness, wow, how does that... how does that even work? :O \$\endgroup\$ – Doorknob Dec 1 '13 at 18:23
  • \$\begingroup\$ @Doorknob it's very clever, but if you substitute the dereferencing and preincrements with indexing b instead, and pretty-print the condition some, you should be able to figure it out. :D (pen and paper also helps, for the resulting truth table) \$\endgroup\$ – FireFly Dec 1 '13 at 19:01
3
\$\begingroup\$

GolfScript (31 chars)

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

Very simple logic: reduce the input modulo 2, then sort a copy. The middle item of the sorted array is in the majority, so look for an index which is different (and hence in the minority).

\$\endgroup\$
3
\$\begingroup\$

Ruby (function body), 42 chars

Assuming 3 numerical arguments a, b, and c:

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

Ruby (command line tool), 61 chars

Version 1 comes in at 62 chars:

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

But, by piggybacking off of Darren Stone's answer, Version 2 gets down to 61 chars:

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

Ruby, 61 chars

w=0
$*.map{|p|w+=w+p.to_i%2}
$><<%w(no\ one C B A)[w>3?w^7:w]
\$\endgroup\$
  • \$\begingroup\$ ['no one',?C,?B,?A] == %w(no\ one C B A) (2 chars saved). \$\endgroup\$ – daniero Jan 4 '14 at 0:54
  • \$\begingroup\$ Nice. Applied that. Thx! \$\endgroup\$ – Darren Stone Jan 4 '14 at 7:56
2
\$\begingroup\$

JavaScript (node), 87 characters

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

To get the ball rolling... expects input as three extra arguments. Makes use of the following pattern for input/output (/ represents "no-one"):

  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
\$\endgroup\$
2
\$\begingroup\$

GolfScript, 36 35 33 characters

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

Takes input as described from STDIN. You can also test the code online.

\$\endgroup\$
2
\$\begingroup\$

Perl, 84 characters.

$x=oct"0b".join"",map{$_%2}<>=~/(\d)/g;print"",('no one','C','B','A')[$x>=4?7-$x:$x]
  • <>=~/(\d)/g parses the input line into distinct digits
  • map{$_%2 takes this list and computes value mod 2 (even or odd)
  • oct"0b".join"", takes this list of mod values, joins them into a string, appends an octal specifier, and converts the string to a number.

Basically what I did was to create a truth table, and then carefully reordered it so I had an inversion operation around $x == 4. So if $x >=4, we did the inversion [$x>=4?7-$x:$x] which we used to index into the array ('no one','C','B','A')

Its not the shortest possible code, but its actually not line noise ... which is remarkable in and of itself.

Perl: 74 characters + 3 flags = 77, run with perl -anE '(code)'

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

This is an improvement, by leveraging autosplit (the -a), say (the -E), and finally figuring out what was wrong with the comparison.

\$\endgroup\$
  • \$\begingroup\$ Why >=4 instead of simply >3? +1 for the tips '0b'. I didn't know before \$\endgroup\$ – F. Hauri Dec 1 '13 at 7:46
  • \$\begingroup\$ I tried both in the debugger ( >3 and >=4), and I am not sure why, but the >=4 worked, but >3 did not. I can't explain it (possibly borked debugger?) to my own satisfaction either \$\endgroup\$ – Joe Dec 1 '13 at 14:23
  • \$\begingroup\$ you seem to have had an extra char in both counts, which I fixed. Also, flags count as characters. \$\endgroup\$ – Doorknob Dec 1 '13 at 23:27
2
\$\begingroup\$

Common Lisp, 114 106 70 chars

From the three values create a pair representing difference in parity between adjacent elements. Treat that as a binary number to index into result list.

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

Older algorithm:

(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")))
\$\endgroup\$
2
\$\begingroup\$

Python 2, 54

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

Mathematica 100 94 89

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

Testing

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

"no one"
"no one"
"B"
"A"
"C"

\$\endgroup\$
1
\$\begingroup\$

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
\$\endgroup\$
1
\$\begingroup\$

R 67

z="no one";c("A","B","C",z,z)[match(2-sum(x<-scan()%%2),c(x,2,-1))]
\$\endgroup\$
  • \$\begingroup\$ Interesting! How could I test this? What do I have to run (maybe a shebang?) \$\endgroup\$ – F. Hauri Dec 2 '13 at 1:53
  • \$\begingroup\$ You'll need to start an interactive R session (e.g. /usr/bin/R) then enter the code above. scan() is what will prompt you for the input: an example would be to type 1[space]3[space]5[space][enter][enter] and you will see the corresponding output (here, no one) printed to the screen. You can download R here: cran.r-project.org/mirrors.html \$\endgroup\$ – flodel Dec 2 '13 at 3:42
1
\$\begingroup\$

C, 85 chars

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

Not as short as my Ruby answer but I'm happy with it, considering the main cruft.

\$\endgroup\$
1
\$\begingroup\$

Fish - 41

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

Stole FireFly's befunge answer and ported it to fish because using registers in fish allows us to shave off some characters. Lost a few characters on not having the horizontal if operator though.

This takes parameters in through arguments.

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
\$\endgroup\$
  • \$\begingroup\$ Ooooooooooo nice! \$\endgroup\$ – F. Hauri Dec 2 '13 at 16:45
  • \$\begingroup\$ Hm, fish huh. Do you have trampoline? if so, maybe you could use (the equivalent of) #@...< at the end to save a char. Oh, and your current code looks like 42 chars to me, so decrement that char-count of yours. :) \$\endgroup\$ – FireFly Dec 2 '13 at 18:18
  • \$\begingroup\$ @FireFly thanks! That did save a char, and you're right, I was over counted by one. My text editor said "col 43" at the end. But of course, cursor on an empty line says "col 1". \$\endgroup\$ – Cruncher Dec 2 '13 at 18:21
1
\$\begingroup\$

Smalltalk, 128 characters

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

send value: with a collection

\$\endgroup\$
1
\$\begingroup\$

JavaScript (ES6) / CoffeeScript, 50 bytes

Uses the truth table as per Firefly's answer but takes a more direct approach in character access:

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>

\$\endgroup\$
0
\$\begingroup\$

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")
\$\endgroup\$
0
\$\begingroup\$

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")
\$\endgroup\$
0
\$\begingroup\$

Two different method in two different languages + variations -> 6 answers

There are essentially 2 way for this operation:

  • array based: Built a binary number of 3 digit, than take answer from an array
  • count based: Count even and odd, and look if there is a count == 1

Perl 71 (array based + variation)

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

One of my shortest perl:

  • s/(.)\s*/$1&1/eg; transform a string like 1 2 3 into 101
  • $==oct"0b".$_; transform binary to oct (same as dec, under 8)
  • $==$=>3?7-$=:$=; if > 3 oper 7-. (From there no one == 0)
  • say$=?chr 68-$=:"no one" if not 0, print char from value, else print no one.

Perl 71 (array based)

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

slightly different in the print step: The output is based on an 'array'.

Perl 81 (count based)

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

Different meaning:

  • $c=A Initialise a counter c with A.
  • map{$a[$_%2]=$c++;$b[$_%2]++}split Counter b count even and odd, a only store which one
  • say$b[0]==1?$a[0]: if even counter == 1 ? also print even player.
  • $b[0]==2?$a[1]: if even counter == 2 ? also print odd player.
  • :"no one" else print no one.

Bash 85 (array based)

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

This is based on my second perl version:

  • c=$((($1%2)<<2|($2&1)*2+($3%2))) make the index pos.
    • $1%2 transform first arg in binary by using mod
    • $2&1 transform second arg in binary by using and
    • <<2 shift-to-the-left is same than *4
    • *2 multiply by 2 is same than <<1.
  • ((c>3))&&c=$((7-c)) if c >= 4 then c = 7-c.
  • o=() declare an array
  • echo ${o[c]} based on array

Bash 133 (count based)

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]=C store player into variable a[even] and a[odd]
  • ((b[$1&1]++));((b[$2&1]++));((b[$3&1]++)) count even/odd into b.
  • case $b in 1) echo ${a[0]} in case even counter==1 print even player
  • 2)echo ${a[1]};; case even counter==2 print odd player
  • *)echo no one;esac else print no one.

Bash 133 (count based)

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)

Same version, using bash's condition and command group instead of case ... esac

\$\endgroup\$
0
\$\begingroup\$

Game Maker Language, 116

My new answer relies heavily on FireFly's formula:

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

The old code compiled with uninitialized variables as 0, 183 characters:

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 - Whole different code

\$\endgroup\$
  • \$\begingroup\$ Interesting!? I didn't know this language before! But as this language does permit the use of array, this code seem not to be the smallest possible for this job. \$\endgroup\$ – F. Hauri Nov 30 '13 at 22:19
  • \$\begingroup\$ @F.Hauri Yes, I'm trying to use arrays to get it shorter. \$\endgroup\$ – Timtech Nov 30 '13 at 22:22
0
\$\begingroup\$

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))))
\$\endgroup\$
0
\$\begingroup\$

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

call with ?z(1,2,3) or assign to a variable with q=z(1,2,3), or even use as a UDF within excel, and use =z(1,2,3) in your excel formula

\$\endgroup\$
0
\$\begingroup\$

Python 3, 80 chars

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

Note: input must be '1' [odd] or '0' [even]. For example:

> 1 1 0
C
> 1 1 1
no one
\$\endgroup\$
  • \$\begingroup\$ The challenge requires the input to be "separated by spaces". Perhaps there is a way to effectively golf a split and join so you can still use your (very smart) int(...input...) idea. ? \$\endgroup\$ – Darren Stone Dec 2 '13 at 19:52
  • \$\begingroup\$ You could remove the '0b'+ I think, at least it looks redundant to me, and just int(input(),2) seems to work in a REPL. \$\endgroup\$ – FireFly Dec 3 '13 at 6:58
  • \$\begingroup\$ @DarrenStone I used a string replace instead, see edit \$\endgroup\$ – Dhara Dec 3 '13 at 8:31
  • \$\begingroup\$ @FireFly Thanks, you're right, I edited my answer. I first tested the code with Python 2, where the '0b' was needed. \$\endgroup\$ – Dhara Dec 3 '13 at 8:32
  • \$\begingroup\$ The challenge also requires the input to accept numbers from 0 to 5. \$\endgroup\$ – Peter Taylor Dec 3 '13 at 10:17
0
\$\begingroup\$

Java, 226 chars

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);
}
\$\endgroup\$
0
\$\begingroup\$

C 101 96

C, probably the most trivial example (some ternary operations):

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);}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.