913-Cat-And-Mouse

Sat 17 May 2025

https://leetcode.com/problems/cat-and-mouse

import pyutil as pyu
pyu.get_local_pyinfo()
print(pyu.ps2("python-dotenv"))
from typing import List
from enum import IntEnum


class State(IntEnum):
  kDraw = 0
  kMouseWin = 1
  kCatWin = 2


class Solution:
  def catMouseGame(self, graph: List[List[int]]) -> int:
    n = len(graph)
    # Result of (cat, mouse, move)
    # Move := 0 (mouse) // 1 (cat)
    states = [[[0] * 2 for i in range(n)] for j in range(n)]
    outDegree = [[[0] * 2 for i in range(n)] for j in range(n)]
    q = deque()  # (cat, mouse, move, state)

    for cat in range(n):
      for mouse in range(n):
        outDegree[cat][mouse][0] = len(graph[mouse])
        outDegree[cat][mouse][1] = len(graph[cat]) - graph[cat].count(0)

    # Start from states that winner can be determined
    for cat in range(1, n):
      for move in range(2):
        # Mouse is in the hole . kMouseWin
        states[cat][0][move] = int(State.kMouseWin)
        q.append((cat, 0, move, int(State.kMouseWin)))
        # Cat catches mouse . kCatWin
        states[cat][cat][move] = int(State.kCatWin)
        q.append((cat, cat, move, int(State.kCatWin)))

    while q:
      cat, mouse, move, state = q.popleft()
      if cat == 2 and mouse == 1 and move == 0:
        return state
      prevMove = move ^ 1
      for prev in graph[cat if prevMove else mouse]:
        prevCat = prev if prevMove else cat
        if prevCat == 0:  # Invalid
          continue
        prevMouse = mouse if prevMove else prev
        # The state is already determined
        if states[prevCat][prevMouse][prevMove]:
          continue
        if prevMove == 0 and state == int(State.kMouseWin) or \
                prevMove == 1 and state == int(State.kCatWin):
          states[prevCat][prevMouse][prevMove] = state
          q.append((prevCat, prevMouse, prevMove, state))
        else:
          outDegree[prevCat][prevMouse][prevMove] -= 1
          if outDegree[prevCat][prevMouse][prevMove] == 0:
            states[prevCat][prevMouse][prevMove] = state
            q.append((prevCat, prevMouse, prevMove, state))

    return states[2][1][0]
new Solution().catMouseGame()

Score: 5

Category: leetcode