16
2
Given two lists of dice rolls for a battle in Risk, your program or function must output how many troops each player loses.
Background
You do not have to read this, for it is merely background. Skip to "Task" subheading to continue unabated.
In the game of Risk, one player can attack another player (in fact, this is necessary to win). The outcome of a battle is determined by the roll of dice. Every battle occurs as a succession of sub-battles in which each player can lose up to 2
of their army pieces.
In a sub-battle, the defender and attacker each roll several dice whose number may vary based on circumstances irrelevant to this challenge. The highest-valued die of the attacker is compared to the highest-valued die of the defender. If the attacker's die is higher than the defender's die, the defender loses one piece. Otherwise, the attacker loses one piece.
Then, if both players have at least two dice, the second-highest valued dice of the two players are compared. Again, if the attacker's die is higher than the defender's die, the defender loses one piece. Otherwise, the attacker loses one piece.
(Defender wins ties. If both defender and attacker roll a 4
, then the attacker loses a piece.)
In this sub-battle from the Wikipedia article, the attacker's dice are red and the defender's dice are white. The highest of the attacker's dice is 4
and the highest of the defender's is 3
. Since the attacker was higher, the defender loses a piece. The second-highest are 3
for the attacker and 2
for the defender. Since the attacker was again higher, the defender loses another piece. Thus in this sub-battle, the attacker loses no pieces and the defender loses 2
pieces.
Note that the third-highest pieces are not compared. This is because the defender has no more than two dice on a single sub-battle, so there are no third-highest pieces to compare ever.
Task
Given the unsorted dice rolls (integers in the range 1 to 6 inclusive) of both the attacker and the defender of a sub-battle of Risk in any convenient form, output the number of army pieces each player loses. The output may be in any convenient form, as long as it has different outputs to indicate the five possibilities. You must indicate what those different outputs are in your question.
The output is determined as follows: Start with def=0
and atk=0
. If the greatest value of the list of dice rolls of the attacker is greater than the greatest value of the list of dice rolls of the defender, then increment def
. Otherwise, increment atk
.
If both lists of dice rolls have length at least 2
, then: if the second-greatest value of the list of dice rolls of the attacker is greater than the second-greatest value of the list, then increment def
and otherwise increment atk
.
Finally, the program or function must output a unique identifier for each of the following 5 output possibilities:
╔═══╦═══╗
║atk║def║
╠═══╬═══╣
║ 1 ║ 0 ║
║ 0 ║ 1 ║
║ 2 ║ 0 ║
║ 1 ║ 1 ║
║ 0 ║ 2 ║
╚═══╩═══╝
Example
Defender: [3, 2]
Attacker: [2, 4, 1]
Max of defender is 3
and max of attacker is 4
. 4>3
, so def=1
Second of defender is 2
and second of attacker is 2
. Not(2>2)
, so atk=1
. The output could then be [1,1]
.
Test Cases
Defender
Attacker
Output (as [def,atk])
-----
[1]
[1]
[0,1]
-----
[6,6]
[1,1,1]
[0,2]
-----
[1,2]
[5,2,3]
[2,0]
-----
[5]
[3,4]
[0,1]
-----
[4]
[4,5]
[1,0]
-----
[1,3]
[1,2,3]
[1,1]
-----
[4]
[4,5,6]
[1,0]
-----
[4,5]
[6,2]
[1,1]
-----
[5]
[6,1,3]
[1,0]
-----
[5,5]
[4,4,1]
[0,2]
-----
[2,5]
[2,2]
[0,2]
-----
[6,6]
[4,4,3]
[0,2]
-----
[2,1]
[4,3]
[2,0]
-----
[4]
[1,5]
[1,0]
-----
[1]
[5,2]
[1,0]
-----
[6,2]
[4]
[0,1]
-----
[4,2]
[2,5,5]
[2,0]
-----
[2]
[6,6,2]
[1,0]
-----
[6]
[2,6]
[0,1]
-----
[3,1]
[1]
[0,1]
-----
[6,2]
[3,5,2]
[1,1]
-----
[4,2]
[1,1]
[0,2]
-----
[4,3]
[5,4,1]
[2,0]
-----
[5,6]
[1,2]
[0,2]
-----
[3,2]
[4,4]
[2,0]
-----
[2]
[6,3,4]
[1,0]
-----
[1,4]
[6,2,4]
[2,0]
-----
[4,2]
[2,5,4]
[2,0]
-----
[5]
[6,2,1]
[1,0]
-----
[3]
[2,5,4]
[1,0]
-----
[5,4]
[2]
[0,1]
-----
[6,3]
[2,6,5]
[1,1]
-----
[3,1]
[4]
[1,0]
-----
[4]
[6,6,5]
[1,0]
-----
[6,3]
[4,2]
[0,2]
-----
[1,6]
[5,4]
[1,1]
-----
[3,6]
[4,4]
[1,1]
-----
[5,4]
[5,1,1]
[0,2]
-----
[6,3]
[5,4]
[1,1]
-----
[2,6]
[1,2]
[0,2]
-----
[4,2]
[3,5,5]
[2,0]
-----
[1]
[1,2,1]
[1,0]
-----
[4,5]
[1,6]
[1,1]
-----
[1]
[3,5,1]
[1,0]
-----
[6,2]
[6,2]
[0,2]
Sample implementation
Python 2 or 3
def risk(atk_rolls,def_rolls):
# set the rolls in descending order, e.g. [5,3,2]
atk_rolls = sorted(atk_rolls,reverse = True)
def_rolls = sorted(def_rolls,reverse = True)
# minimum length.
minlen = min(len(atk_rolls),len(def_rolls))
atk_lost = 0
def_lost = 0
# compare the highest-valued rolls
if atk_rolls[0]>def_rolls[0]:
def_lost += 1
else:
atk_lost += 1
if minlen == 2:
# compare the second-highest-valued rolls
if atk_rolls[1] > def_rolls[1]:
def_lost += 1
else:
atk_lost += 1
return [def_lost, atk_lost]
Specifications
- The input may be taken as any form that clearly encodes only the defender's rolls and the attacker's rolls.
- The output may be in any form that provides a unique output for each of the five possibilities listed above.
- The defender's rolls are a list of
1
or2
integers in the set[1,2,3,4,5,6]
. The attacker's rolls are a list of1
to3
integers in the set[1,2,3,4,5,6]
. - Since this is code-golf, shortest code in each language wins! Do not let answers in golfing languages discourage you from posting answers in other languages.
Saw this on the sandbox, nice question – Noah Cristino – 2017-07-27T19:51:03.347
https://codegolf.meta.stackexchange.com/a/13456/61877 – Noah Cristino – 2017-07-27T19:51:06.197
The attacker loses if its maximum roll is equal to the defender's highest roll, right? – Mr. Xcoder – 2017-07-27T20:02:32.950
1Yes @Mr.Xcoder, the defender wins ties. – fireflame241 – 2017-07-27T20:03:43.100
Hence I deleted the comment :) – Mr. Xcoder – 2017-07-27T20:43:50.240