Katkat

Infection Spread Simulation with Death Threshold

OpenAISoftware Engineer · Technical Screen

Last updated

Implement a cellular automaton simulating epidemic spread on a 2D grid with simultaneous infection and mortality transitions until convergence.

Problem Statement

You are tasked with modeling the spread of a pathogen across a population represented by an m x n grid. Each cell in the grid has one of three possible states:

  • 0: Susceptible (healthy, uninfected)
  • 1: Infected (contagious)
  • 2: Dead (inert, cannot infect or be reinfected)

The simulation advances in discrete time steps (rounds). In each round, all cell transitions occur simultaneously based on the state of the grid at the beginning of that round. Two cells are considered neighbors if they are orthogonally adjacent (up, down, left, or right).

The rules for each round are:

  1. A Susceptible (0) cell becomes Infected (1) if it has at least infect_threshold adjacent Infected (1) neighbors.
  2. An Infected (1) cell transitions to Dead (2) if it has at least death_threshold adjacent Infected (1) neighbors (due to high viral load/overcrowding).
  3. A Dead (2) cell remains Dead (2) indefinitely.

Because state transitions are irreversible (0 -> 1 -> 2), the grid is guaranteed to eventually reach a steady state where no cells change their state.

Implement the function simulate_infection(grid, infect_threshold, death_threshold) that returns the total number of rounds required for the system to reach this steady state. If no cells change state in round 1, return 0.

Function Signature

def simulate_infection(grid: list[list[int]], infect_threshold: int, death_threshold: int) -> int:
    pass

Constraints

  • m == len(grid)
  • n == len(grid[0])
  • 1 <= m, n <= 100
  • grid[i][j] is either 0, 1, or 2
  • 1 <= infect_threshold <= 4
  • 1 <= death_threshold <= 4

Examples

Example 1

Input:
grid = [
    [1, 0],
    [0, 0]
]
infect_threshold = 1
death_threshold = 2

Output: 2

Explanation:

  • Round 1:
    • Cell (0, 0) is infected with 0 infected neighbors, so it stays infected.
    • Cells (0, 1) and (1, 0) each have 1 infected neighbor ((0, 0)), which meets infect_threshold = 1. Both become 1.
    • Cell (1, 1) has 0 infected neighbors and stays 0.
    • Grid becomes [[1, 1], [1, 0]]. (1 round elapsed)
  • Round 2:
    • Cell (0, 0) now has 2 infected neighbors ((0, 1) and (1, 0)), meeting death_threshold = 2. It becomes 2.
    • Cells (0, 1) and (1, 0) have only 1 infected neighbor each ((0, 0)), so they stay 1.
    • Cell (1, 1) has 2 infected neighbors ((0, 1) and (1, 0)), so it becomes 1.
    • Grid becomes [[2, 1], [1, 1]]. (2 rounds elapsed)
  • Round 3:
    • All remaining infected cells have at least 1 neighbor, but none reach death_threshold = 2 without counting the dead cell (0, 0) (only state 1 counts as infected neighbors). Cells (0, 1) and (1, 0) have only (1, 1) as infected neighbor (count 1 = 2), so it dies.
    • Wait, in Round 3: (1, 1) has infected neighbors (0, 1) and (1, 0) (count = 2 >= 2). It transitions to 2.
    • Changes still occur, so Round 3 proceeds to [[2, 1], [1, 2]].
  • Round 4:
    • (0, 1) has 0 infected neighbors (both adjacent are 2). (1, 0) has 0 infected neighbors.
    • No changes occur. Simulation terminates after 3 active rounds.
    • Output: 3

Example 2

Input:
grid = [
    [0, 0],
    [0, 0]
]
infect_threshold = 1
death_threshold = 1

Output: 0

Explanation: There are no infected cells to begin with. The grid is already in steady state, so 0 rounds elapse.

Edge Cases to Consider

  • The grid initially contains only 0s or only 2s (returns 0 immediately).
  • A 1x1 grid (no neighbors can ever exist).
  • State updates must depend on the grid values at the start of the round, not partially updated values.

Hints

Hint 1

Because state updates occur simultaneously, avoid modifying the grid in-place while computing neighbor counts for the current round.

Hint 2

Only count neighbors currently in state 1 (infected); dead cells (state 2) do not contribute to infection or death neighbor thresholds.

Hint 3

Since transitions are unidirectional (0 -> 1 -> 2), the simulation is guaranteed to terminate in at most 2 * m * n rounds; you can optimize by only re-evaluating cells whose neighbors changed in the previous round.

Follow-up questions

  • How would you optimize the simulation if m and n were 10,000 but the number of infected cells was initially very sparse?
  • If infection transitions were probabilistic (e.g., probability p of infection per infected neighbor), how would you structure a Monte Carlo simulation to estimate time to stabilization?
  • How could this simulation be parallelized across multiple workers using domain decomposition, and how would you handle boundary synchronization between steps?