Skip to content

pydsa

Documentation: www.shyal.com/pydsa

Data structure and algorithm helpers for LeetCode-style Python: the functions one keeps rewriting at the top of a solution, written once and tested.

pip install pizza-lib   # the import name is pydsa
from pydsa import table, cells, nbrs, first_true, Multiset, maxheappush

dp = table(3, 4)                      # a 3 by 4 grid of zeros
for i, j in cells(grid):              # every cell, row by row
    for ni, nj in nbrs(grid, i, j):   # its on-grid neighbours
        ...
first_true(1, 10**9, lambda x: x * x >= n)   # the first x in [1, 10^9] with ok(x)

Solves

Each solve is a complete LeetCode solution that uses pydsa, in Python and in mu, a language that transpiles to Python. A third tab, Python, gives the same solve without pydsa. A mu file calls pydsa helpers by name, with no import. The pydsa profile registers them, and the Python that mu prints contains the source of each helper that the file calls.

# 53. Maximum Subarray (Kadane's algorithm)
class Solution
  def maxSubArray(nums: [int]) -> int
    max_diff(scan(+, [0] + nums))[-1]
# 53. Maximum Subarray (Kadane's algorithm)
from itertools import accumulate
from pydsa import max_diff

class Solution:
    def maxSubArray(self, nums: list[int]) -> int:
        return max_diff(accumulate(nums, initial=0))[-1]
# 53. Maximum Subarray (Kadane's algorithm)
class Solution:
    def maxSubArray(self, nums: list[int]) -> int:
        best = cur = -float("inf")
        for x in nums:
            cur = max(x, cur + x)
            best = max(best, cur)
        return best
# 121. Best Time to Buy and Sell Stock (running minimum)
class Solution
  def maxProfit(prices: [int]) -> int
    max([0, *max_diff(prices)])
# 121. Best Time to Buy and Sell Stock (running minimum)
from pydsa import max_diff

class Solution:
    def maxProfit(self, prices: list[int]) -> int:
        return max([0, *max_diff(prices)])
# 121. Best Time to Buy and Sell Stock (running minimum)
class Solution:
    def maxProfit(self, prices: list[int]) -> int:
        low, best = float("inf"), 0
        for p in prices:
            low = min(low, p)
            best = max(best, p - low)
        return best
# 130. Surrounded Regions (connected components)
class Solution
  def solve(board: [[str]])
    for c in components(cells(board, eq='O'), p -> nbrs(board, p, eq='O'))
      if not any(is_edge(board, i, j) for i, j in c)
        put(board, c, 'X')
# 130. Surrounded Regions (connected components)
from pydsa import cells, components, is_edge, nbrs, put

class Solution:
    def solve(self, board: list[list[str]]) -> None:
        for c in components(cells(board, eq="O"), lambda p: nbrs(board, p, eq="O")):
            if not any(is_edge(board, i, j) for i, j in c):
                put(board, c, "X")
# 130. Surrounded Regions (connected components)
class Solution:
    def solve(self, board: list[list[str]]) -> None:
        m, n = len(board), len(board[0])
        st = [
            (i, j)
            for i in range(m)
            for j in range(n)
            if i in (0, m - 1) or j in (0, n - 1)
        ]
        while st:
            i, j = st.pop()
            if 0 <= i < m and 0 <= j < n and board[i][j] == "O":
                board[i][j] = "S"
                st += [(i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1)]
        for row in board:
            row[:] = ["O" if c == "S" else "X" for c in row]
# 200. Number of Islands (connected components)
class Solution
  def numIslands(grid: [[str]]) -> int
    len components(cells(grid, eq='1'), p -> nbrs(grid, p, eq='1'))
# 200. Number of Islands (connected components)
from pydsa import cells, components, nbrs

class Solution:
    def numIslands(self, grid: list[list[str]]) -> int:
        return len(components(cells(grid, eq="1"), lambda p: nbrs(grid, p, eq="1")))
# 200. Number of Islands (connected components)
class Solution:
    def numIslands(self, grid: list[list[str]]) -> int:
        m, n, islands = len(grid), len(grid[0]), 0
        for r in range(m):
            for c in range(n):
                if grid[r][c] == "1":
                    islands += 1
                    stack = [(r, c)]
                    while stack:
                        i, j = stack.pop()
                        if 0 <= i < m and 0 <= j < n and grid[i][j] == "1":
                            grid[i][j] = "0"
                            stack += [(i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1)]
        return islands
# 410. Split Array Largest Sum (binary search on the answer)
class Solution
  def splitArray(nums: [int], k: int) -> int
    first_true(max(nums), sum(nums), cap -> min_chunks(nums, cap) <= k)
# 410. Split Array Largest Sum (binary search on the answer)
from pydsa import first_true, min_chunks

class Solution:
    def splitArray(self, nums: list[int], k: int) -> int:
        return first_true(max(nums), sum(nums), lambda cap: min_chunks(nums, cap) <= k)
# 410. Split Array Largest Sum (binary search on the answer)
from bisect import bisect_left


class Solution:
    def splitArray(self, nums: list[int], k: int) -> int:
        def chunks(cap):
            n, total = 1, 0
            for x in nums:
                n, total = (n + 1, x) if total + x > cap else (n, total + x)
            return n

        lo, hi = max(nums), sum(nums)
        return lo + bisect_left(
            range(lo, hi + 1), True, key=lambda cap: chunks(cap) <= k
        )
# 516. Longest Palindromic Subsequence (dynamic programming)
class Solution
  def longestPalindromeSubseq(s: str) -> int
    lcs(s, s[::-1])
# 516. Longest Palindromic Subsequence (dynamic programming)
from pydsa import lcs

class Solution:
    def longestPalindromeSubseq(self, s: str) -> int:
        return lcs(s, s[::-1])
# 516. Longest Palindromic Subsequence (dynamic programming)
class Solution:
    def longestPalindromeSubseq(self, s: str) -> int:
        n = len(s)
        dp = [0] * n
        for i in range(n - 1, -1, -1):
            dp[i], prev = 1, 0
            for j in range(i + 1, n):
                prev, dp[j] = dp[j], prev + 2 if s[i] == s[j] else max(dp[j], dp[j - 1])
        return dp[-1]
# 542. 01 Matrix (multi-source breadth-first search)
class Solution
  def updateMatrix(mat: [[int]]) -> [[int]]
    grid_bfs(mat, list(cells(mat, eq=0)))
# 542. 01 Matrix (multi-source breadth-first search)
from pydsa import cells, grid_bfs

class Solution:
    def updateMatrix(self, mat: list[list[int]]) -> list[list[int]]:
        return grid_bfs(mat, list(cells(mat, eq=0)))
# 542. 01 Matrix (multi-source breadth-first search)
class Solution:
    def updateMatrix(self, mat: list[list[int]]) -> list[list[int]]:
        m, n = len(mat), len(mat[0])
        q = [(i, j) for i in range(m) for j in range(n) if mat[i][j] == 0]
        dist = [[-1 if v else 0 for v in row] for row in mat]
        for i, j in q:
            for a, b in [(i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1)]:
                if 0 <= a < m and 0 <= b < n and dist[a][b] == -1:
                    dist[a][b] = dist[i][j] + 1
                    q.append((a, b))
        return dist
# 547. Number of Provinces (connected components)
class Solution
  def findCircleNum(isConnected: [[int]]) -> int
    len components(0..<len(isConnected), u -> [v for >v, x in isConnected[u] if x])
# 547. Number of Provinces (connected components)
from pydsa import components

class Solution:
    def findCircleNum(self, isConnected: list[list[int]]) -> int:
        def edges(u):
            return [v for v, x in enumerate(isConnected[u]) if x]

        return len(components(range(len(isConnected)), edges))
# 547. Number of Provinces (connected components)
class Solution:
    def findCircleNum(self, isConnected: list[list[int]]) -> int:
        seen, provinces = set(), 0
        for s in range(len(isConnected)):
            if s not in seen:
                provinces += 1
                st = [s]
                while st:
                    u = st.pop()
                    if u not in seen:
                        seen.add(u)
                        st += [v for v, x in enumerate(isConnected[u]) if x]
        return provinces
# 560. Subarray Sum Equals K (prefix sums)
class Solution
  def subarraySum(nums: [int], k: int) -> int
    count_pairs(scan(+, [0] + nums), want=p -> p - k)
# 560. Subarray Sum Equals K (prefix sums)
from itertools import accumulate
from pydsa import count_pairs

class Solution:
    def subarraySum(self, nums: list[int], k: int) -> int:
        return count_pairs(accumulate(nums, initial=0), want=lambda p: p - k)
# 560. Subarray Sum Equals K (prefix sums)
from collections import Counter


class Solution:
    def subarraySum(self, nums: list[int], k: int) -> int:
        seen, total, count = Counter([0]), 0, 0
        for x in nums:
            total += x
            count += seen[total - k]
            seen[total] += 1
        return count
# 583. Delete Operation for Two Strings (dynamic programming)
class Solution
  def minDistance(word1: str, word2: str) -> int
    len(word1) + len(word2) - 2 * lcs(word1, word2)
# 583. Delete Operation for Two Strings (dynamic programming)
from pydsa import lcs

class Solution:
    def minDistance(self, word1: str, word2: str) -> int:
        return len(word1) + len(word2) - 2 * lcs(word1, word2)
# 583. Delete Operation for Two Strings (dynamic programming)
class Solution:
    def minDistance(self, word1: str, word2: str) -> int:
        dp = list(range(len(word2) + 1))
        for i, a in enumerate(word1, 1):
            prev, dp[0] = dp[0], i
            for j, b in enumerate(word2, 1):
                prev, dp[j] = dp[j], prev if a == b else 1 + min(dp[j], dp[j - 1])
        return dp[-1]
# 695. Max Area of Island (connected components)
class Solution
  def maxAreaOfIsland(grid: [[int]]) -> int
    max from 0 for c in components(cells(grid, eq=1), p -> nbrs(grid, p, eq=1)): len(c)
# 695. Max Area of Island (connected components)
from pydsa import cells, components, nbrs

class Solution:
    def maxAreaOfIsland(self, grid: list[list[int]]) -> int:
        islands = components(cells(grid, eq=1), lambda p: nbrs(grid, p, eq=1))
        return max(map(len, islands), default=0)
# 695. Max Area of Island (connected components)
class Solution:
    def maxAreaOfIsland(self, grid: list[list[int]]) -> int:
        m, n, best = len(grid), len(grid[0]), 0
        for i in range(m):
            for j in range(n):
                st, area = [(i, j)], 0
                while st:
                    a, b = st.pop()
                    if 0 <= a < m and 0 <= b < n and grid[a][b] == 1:
                        grid[a][b] = 0
                        area += 1
                        st += [(a + 1, b), (a - 1, b), (a, b + 1), (a, b - 1)]
                best = max(best, area)
        return best
# 743. Network Delay Time (Dijkstra's algorithm)
class Solution
  def networkDelayTime(times: [[int]], n: int, k: int) -> int
    max(dijkstra(graph(1..n, times, directed=True), k).values()) or -1 if inf
# 743. Network Delay Time (Dijkstra's algorithm)
from math import inf
from pydsa import dijkstra, graph

class Solution:
    def networkDelayTime(self, times: list[list[int]], n: int, k: int) -> int:
        t = max(dijkstra(graph(range(1, n + 1), times, directed=True), k).values())
        return -1 if t == inf else t
# 743. Network Delay Time (Dijkstra's algorithm)
from collections import defaultdict
from heapq import heappop, heappush


class Solution:
    def networkDelayTime(self, times: list[list[int]], n: int, k: int) -> int:
        adj = defaultdict(list)
        for u, v, w in times:
            adj[u].append((v, w))
        dist, pq = {}, [(0, k)]
        while pq:
            d, u = heappop(pq)
            if u not in dist:
                dist[u] = d
                for v, w in adj[u]:
                    heappush(pq, (d + w, v))
        return max(dist.values()) if len(dist) == n else -1
# 778. Swim in Rising Water (binary search on the answer)
class Solution
  def swimInWater(grid: [[int]]) -> int
    reach = t -> grid_bfs(grid, [(0, 0)], ok=v -> v <= t)[-1][-1] >= 0
    first_true(grid[0][0], len(grid) ** 2, reach)
# 778. Swim in Rising Water (binary search on the answer)
from pydsa import first_true, grid_bfs

class Solution:
    def swimInWater(self, grid: list[list[int]]) -> int:
        def reach(t):
            return grid_bfs(grid, [(0, 0)], ok=lambda v: v <= t)[-1][-1] >= 0

        return first_true(grid[0][0], len(grid) ** 2, reach)
# 778. Swim in Rising Water (binary search on the answer)
from bisect import bisect_left


class Solution:
    def swimInWater(self, grid: list[list[int]]) -> int:
        n = len(grid)

        def reach(t):
            seen, st = {(0, 0)}, [(0, 0)]
            while st:
                i, j = st.pop()
                for a, b in [(i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1)]:
                    if (
                        0 <= a < n
                        and 0 <= b < n
                        and (a, b) not in seen
                        and grid[a][b] <= t
                    ):
                        seen.add((a, b))
                        st.append((a, b))
            return (n - 1, n - 1) in seen

        lo = grid[0][0]
        return lo + bisect_left(range(lo, n * n + 1), True, key=reach)
# 875. Koko Eating Bananas (binary search on the answer)
class Solution
  def minEatingSpeed(piles: [int], h: int) -> int
    first_true(1, max(piles), k -> sum(ceil_div(p, k) for p in piles) <= h)
# 875. Koko Eating Bananas (binary search on the answer)
from pydsa import ceil_div, first_true

class Solution:
    def minEatingSpeed(self, piles: list[int], h: int) -> int:
        def ok(k):
            return sum(ceil_div(p, k) for p in piles) <= h
        return first_true(1, max(piles), ok)
# 875. Koko Eating Bananas (binary search on the answer)
from bisect import bisect_left


class Solution:
    def minEatingSpeed(self, piles: list[int], h: int) -> int:
        def ok(k):
            return sum((p + k - 1) // k for p in piles) <= h

        return 1 + bisect_left(range(1, max(piles) + 1), True, key=ok)
# 974. Subarray Sums Divisible by K (prefix sums)
class Solution
  def subarraysDivByK(nums: [int], k: int) -> int
    count_pairs(scan(+, [0] + nums), by=p -> p % k)
# 974. Subarray Sums Divisible by K (prefix sums)
from itertools import accumulate
from pydsa import count_pairs

class Solution:
    def subarraysDivByK(self, nums: list[int], k: int) -> int:
        return count_pairs(accumulate(nums, initial=0), by=lambda p: p % k)
# 974. Subarray Sums Divisible by K (prefix sums)
from collections import Counter


class Solution:
    def subarraysDivByK(self, nums: list[int], k: int) -> int:
        seen, total, count = Counter([0]), 0, 0
        for x in nums:
            total = (total + x) % k
            count += seen[total]
            seen[total] += 1
        return count
# 1011. Capacity To Ship Packages Within D Days (binary search on the answer)
class Solution
  def shipWithinDays(weights: [int], days: int) -> int
    first_true(max(weights), sum(weights), cap -> min_chunks(weights, cap) <= days)
# 1011. Capacity To Ship Packages Within D Days (binary search on the answer)
from pydsa import first_true, min_chunks

class Solution:
    def shipWithinDays(self, weights: list[int], days: int) -> int:
        def fits(cap):
            return min_chunks(weights, cap) <= days

        return first_true(max(weights), sum(weights), fits)
# 1011. Capacity To Ship Packages Within D Days (binary search on the answer)
from bisect import bisect_left


class Solution:
    def shipWithinDays(self, weights: list[int], days: int) -> int:
        def trips(cap):
            n, load = 1, 0
            for w in weights:
                n, load = (n + 1, w) if load + w > cap else (n, load + w)
            return n

        lo, hi = max(weights), sum(weights)
        return lo + bisect_left(range(lo, hi + 1), True, key=lambda c: trips(c) <= days)
# 1020. Number of Enclaves (connected components)
class Solution
  def numEnclaves(grid: [[int]]) -> int
    islands = components(cells(grid, eq=1), p -> nbrs(grid, p, eq=1))
    sum for c in islands if not any(is_edge(grid, i, j) for i, j in c): len(c)
# 1020. Number of Enclaves (connected components)
from pydsa import cells, components, is_edge, nbrs

class Solution:
    def numEnclaves(self, grid: list[list[int]]) -> int:
        islands = components(cells(grid, eq=1), lambda p: nbrs(grid, p, eq=1))
        return sum(
            len(c) for c in islands if not any(is_edge(grid, i, j) for i, j in c)
        )
# 1020. Number of Enclaves (connected components)
class Solution:
    def numEnclaves(self, grid: list[list[int]]) -> int:
        m, n = len(grid), len(grid[0])
        st = [
            (i, j)
            for i in range(m)
            for j in range(n)
            if i in (0, m - 1) or j in (0, n - 1)
        ]
        while st:
            i, j = st.pop()
            if 0 <= i < m and 0 <= j < n and grid[i][j] == 1:
                grid[i][j] = 0
                st += [(i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1)]
        return sum(map(sum, grid))
# 1074. Number of Submatrices That Sum to Target (prefix sums)
class Solution
  def numSubmatrixSumTarget(matrix: [[int]], target: int) -> int
    P = [[0] * len(matrix[0]), *scan((a, b) -> [x + y for x, y in zip(a, b)], matrix)]
    strip = (a, b) -> scan(+, [0] + [y - x for x, y in zip(a, b)])
    sum for i, j in pairs(len(P)): count_pairs(strip(P[i], P[j]), want=s -> s - target)
# 1074. Number of Submatrices That Sum to Target (prefix sums)
from itertools import accumulate
from pydsa import count_pairs, pairs

class Solution:
    def numSubmatrixSumTarget(self, matrix: list[list[int]], target: int) -> int:
        P = [
            [0] * len(matrix[0]),
            *accumulate(matrix, lambda a, b: [x + y for x, y in zip(a, b)]),
        ]

        def strip(a, b):
            return accumulate((y - x for x, y in zip(a, b)), initial=0)

        want = lambda s: s - target
        return sum(count_pairs(strip(P[i], P[j]), want=want) for i, j in pairs(len(P)))
# 1074. Number of Submatrices That Sum to Target (prefix sums)
from collections import Counter


class Solution:
    def numSubmatrixSumTarget(self, matrix: list[list[int]], target: int) -> int:
        P = [[0] * len(matrix[0])]
        for row in matrix:
            P.append([x + y for x, y in zip(P[-1], row)])
        count = 0
        for i, a in enumerate(P):
            for b in P[i + 1 :]:
                seen, total = Counter([0]), 0
                for x, y in zip(a, b):
                    total += y - x
                    count += seen[total - target]
                    seen[total] += 1
        return count
# 1091. Shortest Path in Binary Matrix (breadth-first search)
class Solution
  def shortestPathBinaryMatrix(grid: [[int]]) -> int
    eight = [(a, b) for a in -1..1 for b in -1..1]
    d = grid_bfs(grid, [(0, 0)], ok=v -> not v, dirs=eight)
    grid[0][0] or d[-1][-1] < 0 ? -1 : d[-1][-1] + 1
# 1091. Shortest Path in Binary Matrix (breadth-first search)
from pydsa import ALL_EIGHT, grid_bfs

class Solution:
    def shortestPathBinaryMatrix(self, grid: list[list[int]]) -> int:
        d = grid_bfs(grid, [(0, 0)], ok=lambda v: not v, dirs=ALL_EIGHT)
        return -1 if grid[0][0] or d[-1][-1] < 0 else d[-1][-1] + 1
# 1091. Shortest Path in Binary Matrix (breadth-first search)
class Solution:
    def shortestPathBinaryMatrix(self, grid: list[list[int]]) -> int:
        n = len(grid)
        if grid[0][0]:
            return -1
        dist, q = {(0, 0): 1}, [(0, 0)]
        for i, j in q:
            for a in range(i - 1, i + 2):
                for b in range(j - 1, j + 2):
                    if (
                        0 <= a < n
                        and 0 <= b < n
                        and not grid[a][b]
                        and (a, b) not in dist
                    ):
                        dist[(a, b)] = dist[(i, j)] + 1
                        q.append((a, b))
        return dist.get((n - 1, n - 1), -1)
# 1143. Longest Common Subsequence (dynamic programming)
class Solution
  def longestCommonSubsequence(text1: str, text2: str) -> int
    lcs(text1, text2)
# 1143. Longest Common Subsequence (dynamic programming)
from pydsa import lcs

class Solution:
    def longestCommonSubsequence(self, text1: str, text2: str) -> int:
        return lcs(text1, text2)
# 1143. Longest Common Subsequence (dynamic programming)
class Solution:
    def longestCommonSubsequence(self, text1: str, text2: str) -> int:
        dp = [0] * (len(text2) + 1)
        for a in text1:
            prev = 0
            for j, b in enumerate(text2, 1):
                prev, dp[j] = dp[j], prev + 1 if a == b else max(dp[j], dp[j - 1])
        return dp[-1]
# 1162. As Far from Land as Possible (multi-source breadth-first search)
class Solution
  def maxDistance(grid: [[int]]) -> int
    d = grid_bfs(grid, list(cells(grid, eq=1)))
    max from -1 for i, j in cells(grid, eq=0): d[i][j]
# 1162. As Far from Land as Possible (multi-source breadth-first search)
from pydsa import cells, grid_bfs

class Solution:
    def maxDistance(self, grid: list[list[int]]) -> int:
        d = grid_bfs(grid, list(cells(grid, eq=1)))
        return max((d[i][j] for i, j in cells(grid, eq=0)), default=-1)
# 1162. As Far from Land as Possible (multi-source breadth-first search)
class Solution:
    def maxDistance(self, grid: list[list[int]]) -> int:
        n = len(grid)
        q = [(i, j) for i in range(n) for j in range(n) if grid[i][j]]
        dist = {p: 0 for p in q}
        for i, j in q:
            for a, b in [(i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1)]:
                if 0 <= a < n and 0 <= b < n and (a, b) not in dist:
                    dist[(a, b)] = dist[(i, j)] + 1
                    q.append((a, b))
        return max((d for (i, j), d in dist.items() if not grid[i][j]), default=-1)
# 1248. Count Number of Nice Subarrays (prefix sums)
class Solution
  def numberOfSubarrays(nums: [int], k: int) -> int
    count_pairs(scan(+, [0] + [x % 2 for x in nums]), want=p -> p - k)
# 1248. Count Number of Nice Subarrays (prefix sums)
from itertools import accumulate
from pydsa import count_pairs

class Solution:
    def numberOfSubarrays(self, nums: list[int], k: int) -> int:
        return count_pairs(
            accumulate((x % 2 for x in nums), initial=0), want=lambda p: p - k
        )
# 1248. Count Number of Nice Subarrays (prefix sums)
from collections import Counter


class Solution:
    def numberOfSubarrays(self, nums: list[int], k: int) -> int:
        seen, odd, count = Counter([0]), 0, 0
        for x in nums:
            odd += x % 2
            count += seen[odd - k]
            seen[odd] += 1
        return count
# 1254. Number of Closed Islands (connected components)
class Solution
  def closedIsland(grid: [[int]]) -> int
    islands = components(cells(grid, eq=0), p -> nbrs(grid, p, eq=0))
    count for c in islands if not any(is_edge(grid, i, j) for i, j in c)
# 1254. Number of Closed Islands (connected components)
from pydsa import cells, components, is_edge, nbrs

class Solution:
    def closedIsland(self, grid: list[list[int]]) -> int:
        islands = components(cells(grid, eq=0), lambda p: nbrs(grid, p, eq=0))
        return sum(not any(is_edge(grid, i, j) for i, j in c) for c in islands)
# 1254. Number of Closed Islands (connected components)
class Solution:
    def closedIsland(self, grid: list[list[int]]) -> int:
        m, n = len(grid), len(grid[0])

        def sink(i, j):
            st = [(i, j)]
            while st:
                a, b = st.pop()
                if 0 <= a < m and 0 <= b < n and grid[a][b] == 0:
                    grid[a][b] = 1
                    st += [(a + 1, b), (a - 1, b), (a, b + 1), (a, b - 1)]

        for i in range(m):
            for j in range(n):
                if i in (0, m - 1) or j in (0, n - 1):
                    sink(i, j)
        count = 0
        for i in range(m):
            for j in range(n):
                if grid[i][j] == 0:
                    sink(i, j)
                    count += 1
        return count
# 1334. Find the City With the Smallest Number of Neighbors at a Threshold Distance
# (Dijkstra's algorithm)
class Solution
  def findTheCity(n: int, edges: [[int]], distanceThreshold: int) -> int
    g, t = graph(0..<n, edges), distanceThreshold
    min(reversed(0..<n), key=c -> sum(d <= t for d in dijkstra(g, c).values()))
# 1334. Find the City With the Smallest Number of Neighbors at a Threshold Distance
# (Dijkstra's algorithm)
from pydsa import dijkstra, graph

class Solution:
    def findTheCity(
        self, n: int, edges: list[list[int]], distanceThreshold: int
    ) -> int:
        g, t = graph(range(n), edges), distanceThreshold
        return min(
            reversed(range(n)),
            key=lambda c: sum(d <= t for d in dijkstra(g, c).values()),
        )
# 1334. Find the City With the Smallest Number of Neighbors at a Threshold Distance
# (Floyd-Warshall algorithm)
from math import inf


class Solution:
    def findTheCity(
        self, n: int, edges: list[list[int]], distanceThreshold: int
    ) -> int:
        D = [[0 if i == j else inf for j in range(n)] for i in range(n)]
        for u, v, w in edges:
            D[u][v] = D[v][u] = w
        for k in range(n):
            for i in range(n):
                for j in range(n):
                    D[i][j] = min(D[i][j], D[i][k] + D[k][j])
        return min(
            reversed(range(n)), key=lambda c: sum(d <= distanceThreshold for d in D[c])
        )
# 1971. Find if Path Exists in Graph (connected components)
class Solution
  def validPath(n: int, edges: [[int]], source: int, destination: int) -> bool
    g = adjacency(edges, directed=False)
    any({source, destination} <= set(c) for c in components(0..<n, u -> g[u]))
# 1971. Find if Path Exists in Graph (connected components)
from pydsa import adjacency, components

class Solution:
    def validPath(
        self, n: int, edges: list[list[int]], source: int, destination: int
    ) -> bool:
        g = adjacency(edges, directed=False)
        groups = components(range(n), lambda u: g[u])
        return any({source, destination} <= set(c) for c in groups)
# 1971. Find if Path Exists in Graph (connected components)
from collections import defaultdict


class Solution:
    def validPath(
        self, n: int, edges: list[list[int]], source: int, destination: int
    ) -> bool:
        g = defaultdict(list)
        for u, v in edges:
            g[u].append(v)
            g[v].append(u)
        seen, st = {source}, [source]
        while st:
            for v in g[st.pop()]:
                if v not in seen:
                    seen.add(v)
                    st.append(v)
        return destination in seen

Modules

Module Names
grid table, like, shape, cells, nbrs, in_bounds, is_edge, edges, put, row, col, set_row, set_col, grid_bfs, CARDINALS, DIAGONALS, ALL_EIGHT
adj adjacency, indegrees, levels, components, Graph, graph, dijkstra
search first_true, last_true, first_false, last_false, min_chunks, viz_binary_search
heaps maxheappush, maxheappop, maxheapify, maxheappushpop, maxheapreplace, maxheappeek, maxheapitems, heap, draw_heap
counting Multiset, count_pairs
combo pairs, triples
digits to_digits, to_int, even, odd
arith ceil_div, batched
seq lcs, max_diff
generators as_list
nodes TreeNode, ListNode, GraphNode, Node
tree build_tree, get_level_order, find_node, get_inorder, is_balanced, build_nary_tree, build_general_tree, get_general_tree, generate_random_tree, generate_full_binary_tree, draw_tree, draw_general_tree
bst insert, generate_random_bst, tree_to_list, is_valid_bst, generate_and_print_random_bst
linked build_linked_list, get_list_values, print_linked_list, linked_list_reverse_k, draw_linked_list
graphs build_graph, get_adj_list, build_graph_from_edge_list, as_dict_of_dicts, is_edge_list, draw_graph, draw_graphviz, draw_ascii_graph

Every public name is importable from the package itself. The package imports only the standard library. The draw_* functions, tabulate-style output and viz_binary_search import rich, colorama, PrettyPrintTree and graphviz when first called:

pip install 'pizza-lib[draw]'

Every function has a docstring with its contract; the tests in tests/ are the examples.

Where it comes from

These helpers were the harness of the leet repo, preloaded into builtins for every solve there, and the library that the mu language pastes into the Python it emits. Both still use them from here.

Tests

pip install -e '.[test]'
pytest