# The Yahtzee Scorer

> Dice scoring. Multiple categories evaluated.

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

Domain: Python · Difficulty: medium · Seniority: L3

## Problem

Given 5 dice and a category string, return the score. Categories: 'ones'..'sixes' (sum of dice matching that face), 'three_of_a_kind' (sum of all dice if at least 3 dice share a face, else 0), 'four_of_a_kind' (sum if >=4 share), 'full_house' (25 if 3 of one + 2 of another, else 0), 'small_straight' (30 if 4 consecutive faces), 'large_straight' (40 if 5 consecutive), 'yahtzee' (50 if all 5 same), 'chance' (sum of all 5).

## Worked solution and explanation

### Why this problem exists in real interviews

This tests **conditional logic** driven by **frequency analysis** of dice values. It probes whether a candidate can implement game scoring rules cleanly using a frequency dict and dispatch on the category string.

---

### Break down the requirements

#### Step 1: Build a frequency dict from the dice

Count occurrences of each face value.

#### Step 2: Dispatch on the category string

Map each category to its scoring logic: upper section sums matching dice, n-of-a-kind checks max frequency, full house checks the frequency pattern.

#### Step 3: Return the computed score

Each category returns an integer score.

---

### The solution

**Frequency-based dispatch by category**

```python
def yahtzee_score(dice: list, category: str) -> int:
    freq = {}
    for d in dice:
        freq[d] = freq.get(d, 0) + 1
    total = sum(dice)
    face_map = {"ones": 1, "twos": 2, "threes": 3, "fours": 4, "fives": 5, "sixes": 6}
    if category in face_map:
        face = face_map[category]
        result = face * freq.get(face, 0)
        return result
    max_freq = max(freq.values())
    if category == "three_of_a_kind":
        return total if max_freq >= 3 else 0
    if category == "four_of_a_kind":
        return total if max_freq >= 4 else 0
    if category == "full_house":
        freq_vals = sorted(freq.values())
        return 25 if freq_vals == [2, 3] else 0
    if category == "chance":
        return total
    return 0
```

> **Time and Space Complexity**
>
> **Time:** O(1). Input is always 5 dice with bounded values.
> 
> **Space:** O(1). The frequency dict has at most 6 entries.

> **Interviewers Watch For**
>
> Using a dict for the face-value mapping instead of a long if/elif chain. This is cleaner and more maintainable.

> **Common Pitfall**
>
> For three/four-of-a-kind, the score is the sum of ALL dice, not just the matching ones. This is a common Yahtzee rule that candidates misread.

---

## Common follow-up questions

- How would you add small_straight and large_straight categories? _(Tests consecutive-value detection using sorted unique values.)_
- What if the category string was invalid? _(Tests raising a ValueError or returning 0 with a clear contract.)_
- How would you implement a strategy advisor that picks the best category? _(Tests scoring all categories and returning the maximum.)_

## Related

- [All practice problems](https://datadriven.io/problems)
- [Mock interview mode](https://datadriven.io/interview/the_yahtzee_scorer)
- [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). 100% free data engineering interview prep. Live code execution against Postgres 16, Python 3.11, and Spark sandboxes. No paywall, no premium tier, no signup gate.