Simulate Turn-Based Monster Battles
Company: OpenAI
Role: Machine Learning Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Onsite
Quick Answer: This question evaluates the ability to implement a turn-based battle simulation with correct state management, turn semantics, knockout handling, damage computation, tie-breaking, and performance-aware move selection and type-effectiveness logic.
Part 1: Base Turn-Based Monster Battle Simulation
Constraints
- 0 <= len(team_a), len(team_b) <= 10^5
- Each monster is [hp, atk] with 1 <= hp, atk <= 10^4
- The total number of attacks in the simulated battle will not exceed 2 * 10^5
Examples
Input: ([[5, 3]], [[4, 2]])
Expected Output: ('A', 3, 3)
Explanation: A attacks first and wins after 3 total attacks.
Input: ([[4, 5]], [[3, 1], [6, 2]])
Expected Output: ('B', 1, 4)
Explanation: A knocks out B's first monster immediately, but B's second monster gets the next turn and eventually wins.
Input: ([[2, 2], [10, 4]], [[3, 5]])
Expected Output: ('A', 10, 3)
Explanation: A's first monster falls, then A's second monster finishes the battle.
Input: ([], [[7, 4]])
Expected Output: ('B', 7, 0)
Explanation: If one team starts empty, the other team wins immediately with 0 attacks.
Input: ([], [])
Expected Output: ('Draw', 0, 0)
Explanation: Both teams are empty at the start.
Hints
- Track only the current active monster index and remaining HP for each team.
- When a monster is knocked out, the next monster becomes active immediately, but the next turn still belongs to the other team.
Part 2: Battle Simulation with Monster Types and Effectiveness
Constraints
- 0 <= len(team_a), len(team_b) <= 10^5
- Each monster is [hp, atk, type_id] with 1 <= hp, atk <= 10^4
- 0 <= type_id < len(type_chart)
- type_chart is a square matrix of non-negative multipliers
- The total number of attacks in the simulated battle will not exceed 2 * 10^5
Examples
Input: ([[10, 4, 0]], [[10, 4, 1]], [[1.0, 2.0], [0.5, 1.0]])
Expected Output: ('A', 8, 3)
Explanation: Type 0 is strong against type 1, so A deals 8 damage per hit and wins.
Input: ([[3, 5, 0]], [[2, 1, 1]], [[0.0, 0.0], [1.0, 1.0]])
Expected Output: ('A', 2, 3)
Explanation: A's multiplier is 0, but minimum damage is still 1.
Input: ([[5, 2, 1], [7, 3, 0]], [[4, 4, 0], [6, 2, 1]], [[1.0, 2.0], [0.5, 1.0]])
Expected Output: ('A', 6, 5)
Explanation: Type effects matter across multiple monster switches.
Input: ([], [], [[1.0]])
Expected Output: ('Draw', 0, 0)
Explanation: Both teams are empty at the start.
Hints
- Write a small helper to compute damage from one active monster to the other.
- Even if the type multiplier is 0, the damage rule still forces at least 1 damage.
Part 3: Battle Simulation with Multiple Moves and Best-Move Selection
Constraints
- 0 <= len(team_a), len(team_b) <= 10^5
- Each monster is [hp, atk, type_id, moves] with 1 <= hp, atk <= 10^4
- Each moves list is non-empty
- Each move is [power, move_type] with 1 <= power <= 10^4 and 0 <= move_type < len(type_chart)
- 0 <= type_id < len(type_chart)
- The total number of attacks in the simulated battle will not exceed 2 * 10^5
- The total number of moves across both teams will not exceed 2 * 10^5
Examples
Input: ([[10, 2, 0, [[1, 0], [2, 1]]]], [[6, 1, 1, [[1, 1]]]], [[1.0, 2.0], [0.5, 1.0]])
Expected Output: ('A', 9, 3)
Explanation: A has two equally strong moves against the defender, so the smaller index is chosen. A still wins in 3 attacks.
Input: ([[12, 2, 0, [[2, 0], [2, 1]]]], [[5, 1, 2, [[1, 2]]], [5, 1, 1, [[1, 1]]]], [[1.0, 2.0, 0.5], [0.5, 1.0, 2.0], [2.0, 0.5, 1.0]])
Expected Output: ('A', 11, 3)
Explanation: A should use a different best move against the first and second defenders.
Input: ([[3, 5, 0, [[1, 0]]]], [[2, 1, 1, [[1, 1]]]], [[0.0, 0.0], [1.0, 1.0]])
Expected Output: ('A', 2, 3)
Explanation: Minimum damage 1 still applies after move power and type multiplier are combined.
Input: ([], [[7, 3, 0, [[1, 0]]]], [[1.0]])
Expected Output: ('B', 7, 0)
Explanation: If Team A is empty, Team B wins immediately.
Hints
- For each turn, compare all moves of the active attacker against the current defender's type.
- Tie-breaking is by smallest move index, so keep both the best damage and the index while scanning moves.
Part 4: Optimize Repeated Battles with Large Move Lists
Constraints
- 1 <= len(type_chart) <= 20
- 0 <= len(monster_catalog) <= 10^5
- Each catalog monster is [hp, atk, type_id, moves] with 1 <= hp, atk <= 10^4
- Each moves list is non-empty
- Each move is [power, move_type] with 1 <= power <= 10^4 and 0 <= move_type < len(type_chart)
- 0 <= type_id < len(type_chart)
- The sum of move counts across the whole catalog will not exceed 2 * 10^5
- All battle indices are valid catalog indices
- The total number of simulated attacks across all battle queries will not exceed 2 * 10^5
Examples
Input: ([[10, 2, 0, [[1, 0], [2, 1]]], [6, 1, 1, [[1, 1]]], [5, 3, 0, [[1, 0]]]], [[1.0, 2.0], [0.5, 1.0]], [([0], [1]), ([2], [1])])
Expected Output: [('A', 9, 3), ('A', 5, 1)]
Explanation: The same defender appears in two different battles, and the precomputed best damage makes each turn fast.
Input: ([[12, 2, 0, [[2, 0], [2, 1]]], [5, 1, 2, [[1, 2]]], [5, 1, 1, [[1, 1]]]], [[1.0, 2.0, 0.5], [0.5, 1.0, 2.0], [2.0, 0.5, 1.0]], [([0], [1, 2]), ([1, 2], [0])])
Expected Output: [('A', 11, 3), ('B', 9, 4)]
Explanation: The same strong monster is reused in multiple queries against different team orders.
Input: ([[3, 5, 0, [[1, 0]]], [2, 1, 1, [[1, 1]]]], [[0.0, 0.0], [1.0, 1.0]], [([0], [1]), ([1], [0])])
Expected Output: [('A', 2, 3), ('B', 1, 4)]
Explanation: Minimum damage 1 must still be respected in every query.
Input: ([[7, 3, 0, [[1, 0]]]], [[1.0]], [([], []), ([0], []), ([], [0])])
Expected Output: [('Draw', 0, 0), ('A', 7, 0), ('B', 7, 0)]
Explanation: Edge cases with empty teams should be handled without any attacks.
Hints
- The best move against a defender depends only on the attacker's move list and the defender's type, not on the defender's current HP.
- Precompute, for each catalog monster and each defender type, the best damage it can deal. Then each turn becomes an O(1) lookup.