# Against the House

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

Canonical URL: <https://datadriven.io/problems/against_the_house>

Domain: Python · Difficulty: medium · Seniority: L5

## 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.

## 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

> **Common pitfall**
>
> Checking categories smallest-first. Because a four-of-a-kind and a five-of-a-kind each contain a three-of-a-kind, a ladder that tests 'three alike?' before 'five alike?' catches the big hands in the wrong rung and scores them as a triple. Order the ladder from five down to the fallback and the containment problem disappears.

> **Interviewers watch for**
>
> Whether you notice that three-of-a-kind and the no-match case return the SAME value. There is no separate arithmetic for a triple; it is just sum(dice). Candidates who write a distinct branch for it are pattern-matching on the words, not the values.

---

### 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**

```python
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.

> **Cost**
>
> **Time:** O(1). The input is always 5 dice, so every pass is constant work.
> 
> Space: O(1). The counts dict holds at most 6 entries, one per face value 1 through 6.

---

## Common follow-up questions

- What if you needed to support straights (sequential values)? _(Tests detecting sorted consecutive sequences in the dice values.)_
- How would you rank two hands against each other? _(Tests defining a total ordering on hand types with tiebreakers.)_
- What if the number of dice is variable? _(Tests generalizing the frequency pattern matching beyond fixed-size input.)_
- How would you compute the expected score over all possible rolls? _(Tests probability: enumerate all 6^5 outcomes or use combinatorics to weight each hand type.)_

## Related

- [All practice problems](https://datadriven.io/problems)
- [Mock interview mode](https://datadriven.io/interview/against_the_house)
- [Python Interview Questions](https://datadriven.io/python-interview-questions)
- [Data Engineering Interview Prep Guide](https://datadriven.io/data-engineer-interview-prep)
- [Daily Challenge](https://datadriven.io/daily)

---

Source: DataDriven (https://datadriven.io). DataDriven is the data engineering interview community. Live code execution in SQL, Python, and Spark sandboxes. Every feature is open to every member.