Multiplayer Rock-Paper-Scissors
Python, 41 bytes
lambda r,s,p:[s>p<=r>0,p>r<=s>0,r>s<=p>0]
Try it online!
Takes counts as (r,s,p)
. Outputs a three-element list with True
at the position of the winner, or all False
's if there's a tie or only a single figure appearing.
Rock: [True, False, False]
Scissors: [False, True, False]
Paper: [False, False, True]
Tie: [False, False, False]
We use an alternate characterization without multiplication (except when only one figure is present). Below is the condition for Rock winning, with Scissors and Paper having similar conditions.
Rock wins if: Paper has the fewest, strictly fewer than Scissors but possibly the same as Rock.
We can write this in Python as s>p<=r
using inequality chaining.
Unfortunately, this doesn't correctly handle the special case when r=p=0
, saying that Rock wins even though only Scissors is present. To fix this, we strengthen the condition for Rock to win to include r>0
via s>p<=r>0
, which makes the only-Scissors case give all False
for every condition, matching a tie.
44 bytes
lambda r,s,p:r*s==s*p==p*r or[s>p<=r,p>r<=s]
Try it online!
Takes counts as (r,s,p)
. Outputs as:
Rock: [True, False]
Scissors: [False, True]
Paper: [False, False]
Tie: True
The "Tie" case also includes where there's only a single figure present.
05AB1E, 14 13 bytes
Ćü*ZÊ2βD3*7%M
Input as a list of integers in the order \$[r,s,p]\$.
Output as one of the following four:
Rock wins: 3
Scissors wins: 5
Paper wins: 6
Tie: 0
-1 byte thanks to @xnor.
Try it online or verify some more test cases.
Explanation:
Ć # Enclose the (implicit) input-list, appending its own head
# i.e. input=[3,2,2] → STACK: [[3,2,2,3]
ü # For each overlapping pair: [a,b,c,d] → [[a,b],[b,c],[c,d]]
* # Multiply them together
# STACK: [[6,4,6]]
Z # Get the maximum (without popping)
# STACK: [[6,4,6],6]
Ê # Check which of the values in the list are NOT equals to this maximum
# STACK: [[0,1,0]]
2β # Convert this list of 0s and 1s from a binary list to integer
# STACK: [2]
D # Duplicate it
# STACK: [2,2]
3* # Multiply it by 3
# STACK: [2,6]
7% # Take modulo-7:
# STACK: [2,6]
M # Push the largest value on the stack
# STACK: [2,6,6]
# (after which the top of the stack is output implicitly as result)
After the Ćü*ZÊ
we can have the following values:
One of:
Rock wins: [[0,1,1], [0,0,1]]
Scissors wins: [[1,0,1], [1,0,0]]
Paper wins: [[1,1,0], [0,1,0]]
Ties: [[0,0,0]]
Converting those from binary-lists to integers:
One of:
Rock wins: [3, 1]
Scissors wins: [5, 4]
Paper wins: [6, 2]
Ties: [0]
The 3*7%
(thanks to @xnor!) will map the lower values to the higher values in the pair, and will also unsure the lower values won't increase.
This works because the pairs
[1,3], [2,6], [4,5]
are constructed from bits where the second number has two bits set: that of the first number, and the bit position to its right, wrapping around in 3 bits. This comes from the binary-list of the RPS game. We can do the set-next-bit with*3
and enforce 3-bit wrapping with%7
.
One of:
Rock wins: [3→2, 1→3]
Scissors wins: [5→1, 4→5]
Paper wins: [6→4, 2→6]
Ties: [0]
After which we can use M
to only keep the largest value on the stack for our result:
One of:
Rock wins: [3, 3]
Scissors wins: [5, 5]
Paper wins: [6, 6]
Ties: [0]
C (gcc), 61 \$\cdots\$ 53 52 bytes
Saved 3 bytes thanks to Kevin Cruijssen!!!
Saved 3 bytes thanks to Arnauld!!!
Saved a byte thanks to ceilingcat!!!
Uses xnor's formula converted to \$3\$ for Rock, \$2\$ for Scissors, \$1\$ for Paper, and \$0\$ for a tie or only a single figure appearing.
f(r,s,p){r=s>p&p<=r&&r?3:p>r&r<=s&&s?2:r>s&s<=p&&p;}
Try it online!