16
\$\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\$
5
  • 7
    \$\begingroup\$ Might be more interesting as a [king-of-the-hill]. Play the game. \$\endgroup\$ Commented Dec 1, 2013 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\$ Commented Dec 2, 2013 at 11:16
  • \$\begingroup\$ @OlivierDulac, 0 is also an even number. \$\endgroup\$ Commented Dec 2, 2013 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\$ Commented Dec 2, 2013 at 12:38
  • \$\begingroup\$ @PeterTaylor: thanks, I misread the question (and I didn't think it would count). \$\endgroup\$ Commented Dec 2, 2013 at 13:04

32 Answers 32

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\$
1
  • \$\begingroup\$ Nice, good use of array-oriented programming to compute the index. \$\endgroup\$
    – FireFly
    Commented Nov 30, 2013 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\$
1
4
\$\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\$
3
  • \$\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
    Commented Dec 1, 2013 at 18:18
  • \$\begingroup\$ In Ruby: s = "=**++b+**(++" :P in all seriousness, wow, how does that... how does that even work? :O \$\endgroup\$
    – Doorknob
    Commented Dec 1, 2013 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
    Commented Dec 1, 2013 at 19:01
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\$
1
  • \$\begingroup\$ I ported this to fish for my answer. I noted you. +1 btw \$\endgroup\$
    – Cruncher
    Commented Dec 2, 2013 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\$

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\$
2
  • \$\begingroup\$ ['no one',?C,?B,?A] == %w(no\ one C B A) (2 chars saved). \$\endgroup\$
    – daniero
    Commented Jan 4, 2014 at 0:54
  • \$\begingroup\$ Nice. Applied that. Thx! \$\endgroup\$ Commented Jan 4, 2014 at 7:56
3
\$\begingroup\$

Python 2, 54

f=lambda a,b,c:[['no one','C'],'BA'][(a^b)&1][(a^c)&1]
\$\endgroup\$
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\$
0
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\$

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\$
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\$
3
  • \$\begingroup\$ Why >=4 instead of simply >3? +1 for the tips '0b'. I didn't know before \$\endgroup\$ Commented Dec 1, 2013 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
    Commented Dec 1, 2013 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
    Commented Dec 1, 2013 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\$
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\$

R 67

z="no one";c("A","B","C",z,z)[match(2-sum(x<-scan()%%2),c(x,2,-1))]
\$\endgroup\$
2
  • \$\begingroup\$ Interesting! How could I test this? What do I have to run (maybe a shebang?) \$\endgroup\$ Commented Dec 2, 2013 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
    Commented Dec 2, 2013 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\$
3
  • \$\begingroup\$ Ooooooooooo nice! \$\endgroup\$ Commented Dec 2, 2013 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
    Commented Dec 2, 2013 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
    Commented Dec 2, 2013 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\$

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

Vyxal 3, 18 bytes

eB"0CBA"ṁi0"5FZᵃ”r

Try it Online!

-11 bytes thanks to @Aaroneous MIller

Explanation (Outdated):

euL1=["5FZᵃ”|:1Cv[0Ḟ|1Ḟ}kAi­⁡​‎‎⁡⁠⁡‏⁠‏���⁡⁠⁡‌⁢​‎‎⁡⁠⁢‏⁠‎⁡⁠⁣‏⁠‎⁡⁠⁤‏⁠‎⁡⁠⁢⁡‏‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁢⁢‏⁠‎⁡⁠⁢⁣‏⁠‎⁡⁠⁢⁤‏⁠‎⁡⁠⁣⁡‏⁠‎⁡⁠⁣⁢‏⁠‎⁡⁠⁣⁣‏⁠‎⁡⁠⁣⁤‏‏​⁡⁠⁡‌⁤​‎‎⁡⁠⁤⁡‏⁠⁠⁠⁠⁠‏​⁡⁠⁡‌⁢⁡​‎‎⁡⁠⁤⁢‏⁠⁠⁠‏​⁡⁠⁡‌⁢⁢​‎‎⁡⁠⁤⁣‏⁠‎⁡⁠⁤⁤‏‏​⁡⁠⁡‌⁢⁣​‎‎⁡⁠⁢⁡⁡‏‏​⁡⁠⁡‌⁢⁤​‎‎⁡⁠⁢⁡⁢‏⁠‎⁡⁠⁢⁡⁣‏⁠‎⁡⁠⁢⁡⁤‏‏​⁡⁠⁡‌⁣⁡​‎‎⁡⁠⁢⁢⁡‏⁠‎⁡⁠⁢⁢⁢‏⁠‎⁡⁠⁢⁢⁣‏⁠‎⁡⁠⁢⁢⁤‏‏​⁡⁠⁡‌⁣⁢​‎‎⁡⁠⁢⁣⁡‏⁠‎⁡⁠⁢⁣⁢‏‏​⁡⁠⁡‌⁣⁣​‎‎⁡⁠⁢⁣⁣‏‏​⁡⁠⁡‌­
e                            ## ‎⁡Calculate every element of list if it's even
 uL1=                        ## ‎⁢Contains only even or odd integers?
     ["5FZᵃ”                 ## ‎⁣If so, print "no one" 😔
            |                ## ‎⁤else
             :               ## ‎⁢⁡duplicate
              1C             ## ‎⁢⁢how many even integers the list has
                v            ## ‎⁢⁣decremented
                 [0Ḟ         ## ‎⁢⁤If the number of the even integers is 1, find 0
                    |1Ḟ}     ## ‎⁣⁡if not, find 1
                        kA   ## ‎⁣⁢uppercase alphabet
                          i  ## ‎⁣⁣index
💎

Created with the help of Luminespire.

\$\endgroup\$
3
  • \$\begingroup\$ Try it Online! for 20 bytes (the header is just to set up some test cases) \$\endgroup\$ Commented Dec 2, 2023 at 3:44
  • \$\begingroup\$ Actually, make that 18 bytes \$\endgroup\$ Commented Dec 2, 2023 at 3:47
  • \$\begingroup\$ @AaroneousMiller Done! \$\endgroup\$
    – Fmbalbuena
    Commented Dec 2, 2023 at 16:47
1
\$\begingroup\$

Perl 5 -p, 49 bytes

$_=(0,C,B,A,A..C)[oct"0b".s/./$&%2/ger]||"no one"

Try it online!

Takes input as three digits with no spaces between.

\$\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\$
2
  • \$\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\$ Commented Nov 30, 2013 at 22:19
  • \$\begingroup\$ @F.Hauri Yes, I'm trying to use arrays to get it shorter. \$\endgroup\$
    – Timtech
    Commented Nov 30, 2013 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\$

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