The Scoreboard Race
A medium Python interview practice problem on DataDriven. Write the Python and run it against test cases, with instant feedback.
- Domain
- Python
- Difficulty
- medium
- Seniority
- L3
- Asked in
- Optiver
Problem
You are replaying a recorded dice game from its log of rolls. Deal the values in rolls one at a time around the table in seating order (player 0, then player 1, wrapping back to player 0 after the last player), adding each value to that player's running total. The game ends the instant any player's total reaches or passes target, even mid-round before the remaining players have rolled; return all num_players scores, indexed by player, at that moment.
The first to cross the line ends the game, mid-round or not.
Example 1
Input:
num_players = 2, target = 10, rolls = [3,5,4,2,6,1]
Output:
[13,7]
Example 2
Input:
num_players = 3, target = 8, rolls = [5,1,2,4,3,6]
Output:
[9,1,2]
Worked solution and explanation
What this really is
Strip the dice theme away and this is a bounded simulation with an early-exit condition, and the entire problem lives in WHERE you put the exit check. The tell that sinks people: the rolls list is longer than the game. You are handed enough rolls to guarantee a finish, but the game stops the instant someone crosses target, usually mid-round with rolls still left in the list. Read the task as 'consume every roll' and you will keep dealing past the win and report scores that never actually happened.
Build it in pieces
Step 1: Initialize one score per player
One running total per player. [0] * num_players is the clean way; a manual append loop works but reads worse.
Step 2: Deal each roll to the right seat
Walk the rolls in order. The player for roll i is i % num_players, which deals them around the table and wraps automatically. No separate turn counter to keep in sync.
Step 3: Check the winner where the win can happen
Right after adding a roll, compare only THAT player's score to target. They are the only one who could have just crossed it, so you do not rescan everyone. The moment it reaches or passes target, stop.
Step 4: Return final scores
Return the score list as-is. The crossing score is reported raw, not clamped to target.
The solution
def dice_race(num_players, target, rolls):
scores = [0] * num_players
for roll_idx, roll in enumerate(rolls):
player = roll_idx % num_players
scores[player] += roll
if scores[player] >= target:
break
return scores- Check at end of round
- Let every player roll, then test all scores. A player who crosses target on the first seat still 'lets' later players roll, inflating their totals. Produces scores the game would never reach.
- Check after each roll
- Test the one player who just rolled. The first crossing stops everything, so later seats keep the totals they had. This is the behavior the expected outputs encode.
Common follow-up questions
- What if the game continued until every player crossed the target, recording finish order? (Tests changing the termination condition and tracking who has already finished.)
- What if each player rolled two dice per turn? (Tests summing multiple rolls per player per turn before checking.)
- How would you run this with random rolls instead of a fixed log? (Tests using random.randint(1, 6) with random.seed for reproducibility.)
- What if you needed the full round-by-round history, not just final scores? (Tests appending a per-round snapshot to a history list.)