Against the House

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
L5
Asked in
Optimove

Problem

Given exactly 5 dice values (integers 1-6), return the best score using these priorities: five-of-a-kind = 50; four-of-a-kind = 40; full-house (three of one value + two of another) = 25; three-of-a-kind = sum of all 5 dice; otherwise = sum of the dice.

Five little fates land, and only the bold read them right.

Example 1

Input:

dice = [4,4,4,4,4]

Output:

50

Example 2

Input:

dice = [2,2,2,2,5]

Output:

40

Worked solution and explanation

What this really is

Strip the dice costume and this is a frequency-count problem with a priority ladder bolted on. The real skill: turn 'the best pattern wins' into a count of how many times each face shows up, then test the patterns strongest-first. Anyone can add five numbers. What separates candidates is the ordering. A five-of-a-kind also contains a three-of-a-kind, so if you check the small pattern first you hand back the sum when the answer should be 50. The quieter trap: three-of-a-kind and 'nothing matches' both return the plain sum, so people invent a special case for the triple that does not exist.


The trap


Build it

Step 1: Count how often each face appears

Walk the five dice and tally each face into a dict. Now the whole hand is described by those counts, not by the raw order of the dice.

Step 2: Read the pattern off the counts

The single most useful fact is the largest count: 5, 4, or 3 names the top three tiers directly. For the full house you also need to know a pair rides alongside the triple, which is just asking whether any face has a count of exactly 2.

Step 3: Walk the ladder strongest-first

Test top count 5, then 4, then (3 with a pair) for the full house. Everything else, including a bare triple, falls through to the sum of the dice. Highest-first ordering is what keeps a big hand from being caught in a smaller rung.

Frequency count plus a strongest-first ladder
def dice_roll_scoring(dice):
    counts = {}
    for value in dice:
        if value not in counts:
            counts[value] = 0
        counts[value] += 1

    total = 0
    for value in dice:
        total += value

    top_count = 0
    for value in counts:
        if counts[value] > top_count:
            top_count = counts[value]

    if top_count == 5:
        return 50
    if top_count == 4:
        return 40
    if top_count == 3 and 2 in counts.values():
        return 25
    return total

No sorting needed: the largest count alone names the top tiers, and a lone check for a pair separates the full house.

Smallest-first (wrong)
Check 'any face appears 3 times?' before the bigger hands. A five-of-a-kind has a face appearing 5 times, which is also >= 3, so it matches the triple rung and scores the sum. Five 4s returns 20 instead of 50.
Strongest-first (correct)
Check top count == 5, then == 4, then the full house, then fall through. Each bigger hand is caught before the ladder ever reaches the triple test, so containment never mis-scores.

Common follow-up questions