Question Details
Tennis Score Game ## Problem Overview Design a two-player game with three core methods: * add_score(player) * get_score() * get_result() The interview then adds a
follow-up convert the score
Full Details
Tennis Score Game ## Problem Overview Design a two-player game with three core methods: * add_score(player) * get_score() * get_result() The interview then adds a
follow-up convert the score into a human-readable tennis-style format such as love, 15-30, and deuce. In Part 1, scores are stored as raw point counts. In Part 2, those raw counts are rendered using standard tennis terminology. This is the classic tennis scoring question with one explicit normalization rule: * A player must lead by 2 points to win. * If the game reaches a tie after 3-3, collapse it back to 3-3 immediately. * 4-4 becomes 3-3 * That means later tied states such as 5-5 never persist as observable scores You can assume there are exactly two players. ## Part 1: Numeric Game API
Problem Statement Implement a Game class with these methods:
python class Game: def add_score(self, player: str) -> None: pass def get_score(self) -> tuple[int, int]: pass def get_result(self) -> str | None: pass
Requirements * Only two players exist. * add_score(player) increments the specified player's score. * get_score()
returns the current numeric score for both players. * get_result()
returns the winner once someone is ahead by at least 2 points and has at least 4 points. * When the score becomes tied after 3-3, normalize it back to 3-3 immediately.
Example
python game = Game("player1", "player2") game.add_score("player1") # 1-0 game.add_score("player2") # 1-1 game.add_score("player1") # 2-1 game.add_score("player1") # 3-1 game.get_score() # (3, 1) game.get_result() # None game.add_score("player2") # 3-2 game.add_score("player2") # 3-3 game.add_score("player1") # 4-3 game.add_score("player2") # 4-4 -> normalize to 3-3 game.get_score() # (3, 3) game.get_result() # None
Part 1 Solution
python class Game: def __init__(self, player1: str, player2: str): self.player1 = player1 self.player2 = player2 self.scores = { player1: 0, player2: 0, } def add_score(self, player: str) -> None: if player not in self.scores: raise ValueError(f"Unknown player: {player}") if self.get_result() is not None: raise ValueError("Game already has a winner") self.scores[player] += 1 self._normalize_deuce() def get_score(self) -> tuple[int, int]:
**return** (self.scores[self.player1], self.scores[self.player2]) def get_result(self) -> str | None: p1 = self.scores[self.player1] p2 = self.scores[self.player2] if max(p1, p2) >= 4 and abs(p1 - p2) >= 2:
**return** self.player1 if p1 > p2 else self.player2 return None def _normalize_deuce(self) -> None: p1 = self.scores[self.player1] p2 = self.scores[self.player2] if p1 >= 4 and p1 == p2: self.scores[self.player1] = 3 self.scores[self.player2] = 3
Complexity * add_score: O(1) * get_score: O(1) * get_result: O(1) * Space: O(1) ## Part 2: Match Wrapper + Human Score
Problem Statement Now write a Match class that builds a Game object internally and exposes a human-readable score using tennis terms.
python class Match: def __init__(self, player1: str, player2: str): pass def point_won_by(self, player: str) -> None: pass def score(self) -> str: pass def result(self) -> str | None: pass
Human Score Rules * 0 maps to love * 1 maps to 15 * 2 maps to 30 * 3 maps to 40 * Tied scores below 3-3 are rendered normally, such as love-love, 15-15, and 30-30 * Raw 3-3 corresponds to tennis 40-40, which is rendered as deuce * Raw 4-3 or 3-4 is advantage <player> * If a player wins,
return winner <player> Because tied scores above 3-3 collapse back to 3-3, deuce naturally reappears after advantage is lost.
Example
python match = Match("alice", "bob") match.point_won_by("alice") match.score() # "15-love" match.point_won_by("bob") match.point_won_by("alice") match.point_won_by("bob") match.point_won_by("alice") match.point_won_by("bob") match.score() # "deuce" match.point_won_by("alice") match.score() # "advantage alice" match.point_won_by("bob") match.score() # "deuce" match.point_won_by("bob") match.score() # "advantage bob" match.point_won_by("bob") match.result() # "winner bob"
Part 2 Solution
python class Match: SCORE_LABELS = { 0: "love", 1: "15", 2: "30", 3: "40", } def __init__(self, player1: str, player2: str): self.game = Game(player1, player2) def point_won_by(self, player: str) -> None: self.game.add_score(player) def score(self) -> str: winner = self.game.get_result() if winner is not None:
**return** f"winner {winner}" p1, p2 = self.game.get_score() player1 = self.game.player1 player2 = self.game.player2 if p1 >= 3 and p2 >= 3: if p1 == p2:
**return** "deuce" leader = player1 if p1 > p2 else player2 return f"advantage {leader}"
**return** f"{self.SCORE_LABELS[p1]}-{self.SCORE_LABELS[p2]}" def result(self) -> str | None: winner = self.game.get_result() if winner is None:
**return** None return f"winner {winner}"
Topics
More from Reddit
About Reddit Interview Reports
This question was reported by a candidate who interviewed at Reddit. LeakCode aggregates interview reports from 10+ sources, including 1Point3Acres, Glassdoor, LeetCode Discuss, Blind, Reddit, Indeed, and Nowcoder. Each report is translated where necessary, deduplicated against existing entries, and tagged by company, role, round type, and reporting date.
Use this question as one calibration data point, not a memorization target. Companies typically rotate their question pools every 2-4 months; the exact wording of a 2024 question may differ from what you encounter today. The underlying pattern, difficulty level, and follow-up depth at Reddit are the higher-signal extractions to take from this report.
For broader preparation context, the Reddit interview process typically includes a recruiter screen, one or two technical phone screens, and a 4-5 round on-site loop covering coding, system design (at L4+ levels), and behavioral. Reports tagged on LeakCode show the round-by-round distribution and typical difficulty calibration. To browse questions filtered by round type and seniority, use the company hub linked above.
How To Practice This Type of Question
Solve similar problems on LeetCode under timed conditions (25-35 minutes per medium difficulty). The goal is pattern recognition: recognize the underlying technique (sliding window, two-pointer, BFS, memoized recursion, etc.) within 60-90 seconds of reading. Strong candidates verbalize their hypothesis out loud before coding, then iterate based on feedback. Weak candidates dive into implementation immediately, lose time on the wrong approach, and run out of time for follow-ups.
Companies update their question pools every 2-4 months. The exact wording of any given question may have been retired by the time you interview. Focus your prep on the pattern, not the specific problem. The patterns that appear in Reddit reports consistently are the ones worth investing in; one-off niche problems are not.
During Your Reddit Round
Apply the standard interview round template: clarify requirements (2-3 minutes), state your approach out loud and confirm direction with the interviewer (3-5 minutes), code with narration (15-25 minutes), test with concrete examples including edge cases (5 minutes), discuss optimization or trade-offs if time permits (5 minutes). This template is universally accepted across FAANG and adjacent companies; deviating from it produces weaker interviewer feedback signal.
The single most predictive failure mode in Reddit reports tagged "no hire": not asking clarifying questions. Interviewers are explicitly trained to weight this. Strong candidates ask 3-5 clarifying questions even on problems that look obvious; weak candidates dive into code immediately. The clarifying-question check is often the first signal recorded in the interviewer's written notes.