Reference patterns for mathematical and combinatorial problem-solving. Covers modular arithmetic, prime sieves, GCD/LCM, binomial coefficients, fast exponentiation, counting techniques, inclusion-exclusion, and game theory. Load this skill when a problem involves number theory, combinatorics, modular operations, or strategic game analysis.
Provides mathematical and combinatorial algorithms for number theory, counting, and game theory problems.
/plugin marketplace add sequenzia/agent-alchemy/plugin install agent-alchemy-cs-tools@agent-alchemyThis skill inherits all available tools. When active, it can use any tool Claude has access to.
Mathematical and combinatorial problems appear frequently in competitive programming and algorithm design. They often hide behind constraints that look like brute-force problems but require algebraic shortcuts to meet time limits. This reference covers eight core pattern families with recognition signals, templates, and pitfalls.
| Trigger Signals | Technique | Typical Complexity |
|---|---|---|
| "answer modulo 10^9+7", large product/sum | Modular Arithmetic | O(1) per operation |
| "count primes up to N", "smallest factor" | Sieve of Eratosthenes | O(N log log N) |
| "greatest common divisor", "least common multiple" | GCD / LCM | O(log min(a,b)) |
| "how many ways to choose", "combinations mod p" | Binomial Coefficients | O(N) precompute, O(1) query |
| "compute a^b mod m", "matrix recurrence" | Fast Exponentiation | O(log b) |
| "count arrangements", "distribute items into groups" | Counting Techniques | Varies |
| "count elements satisfying at least one", "derangements" | Inclusion-Exclusion | O(2^k) for k constraints |
| "two players, optimal play", "who wins" | Game Theory (Sprague-Grundy) | Varies by state space |
Recognition Signals
Core Idea
All arithmetic operations (add, subtract, multiply) distribute over modulo. Division under a prime modulus uses modular inverse: a / b mod p = a * b^(p-2) mod p via Fermat's little theorem. Always reduce intermediate results to prevent overflow.
Python Template
MOD = 10**9 + 7
def mod_add(a: int, b: int) -> int:
return (a + b) % MOD
def mod_mul(a: int, b: int) -> int:
return (a * b) % MOD
def mod_pow(base: int, exp: int, mod: int = MOD) -> int:
result = 1
base %= mod
while exp > 0:
if exp & 1:
result = result * base % mod
exp >>= 1
base = base * base % mod
return result
def mod_inv(a: int, mod: int = MOD) -> int:
"""Modular inverse via Fermat's little theorem. Requires mod is prime."""
return mod_pow(a, mod - 2, mod)
def mod_div(a: int, b: int) -> int:
return mod_mul(a, mod_inv(b))
Key Edge Cases
(a - b + MOD) % MODmod_inv(0) is undefined; guard against itCommon Mistakes
Recognition Signals
Core Idea
The classic sieve marks composites by iterating through multiples of each prime. The smallest-prime-factor (SPF) variant stores the smallest divisor at each index, enabling O(log N) factorization of any number after an O(N log log N) precompute. For ranges beyond memory, use a segmented sieve.
Python Template
def sieve_primes(n: int) -> list[bool]:
"""Standard boolean sieve. is_prime[i] is True if i is prime."""
is_prime = [True] * (n + 1)
is_prime[0] = is_prime[1] = False
for i in range(2, int(n**0.5) + 1):
if is_prime[i]:
for j in range(i * i, n + 1, i):
is_prime[j] = False
return is_prime
def smallest_prime_factor(n: int) -> list[int]:
"""SPF sieve for fast factorization."""
spf = list(range(n + 1))
for i in range(2, int(n**0.5) + 1):
if spf[i] == i: # i is prime
for j in range(i * i, n + 1, i):
if spf[j] == j:
spf[j] = i
return spf
def factorize(x: int, spf: list[int]) -> list[int]:
"""Factorize x using precomputed SPF table."""
factors: list[int] = []
while x > 1:
factors.append(spf[x])
x //= spf[x]
return factors
Key Edge Cases
Common Mistakes
2*i instead of i*i (correct but slower)n+1 slots)sieve[0] and sieve[1] are not primeRecognition Signals
Core Idea
Euclidean algorithm computes GCD in O(log min(a,b)). LCM derives from GCD: lcm(a,b) = a * b // gcd(a,b). Extended Euclidean finds coefficients x, y such that a*x + b*y = gcd(a,b), which is essential for modular inverse when the modulus is not prime.
Python Template
from math import gcd
from functools import reduce
def lcm(a: int, b: int) -> int:
return a * b // gcd(a, b)
def lcm_array(arr: list[int]) -> int:
return reduce(lcm, arr)
def gcd_array(arr: list[int]) -> int:
return reduce(gcd, arr)
def extended_gcd(a: int, b: int) -> tuple[int, int, int]:
"""Returns (g, x, y) such that a*x + b*y = g = gcd(a, b)."""
if b == 0:
return a, 1, 0
g, x1, y1 = extended_gcd(b, a % b)
return g, y1, x1 - (a // b) * y1
def mod_inv_ext(a: int, m: int) -> int:
"""Modular inverse via extended GCD. Works for any coprime a, m."""
g, x, _ = extended_gcd(a % m, m)
if g != 1:
raise ValueError(f"Inverse does not exist: gcd({a}, {m}) = {g}")
return x % m
Key Edge Cases
gcd(0, x) = x and gcd(0, 0) = 0 by conventiona // gcd(a,b) * b instead of a * b // gcd(a,b)b = 0: base case returns (a, 1, 0)Common Mistakes
gcd(a, m) != 1Recognition Signals
Core Idea
For small n (up to ~10^6), precompute factorials and inverse factorials modulo a prime, then answer nCr queries in O(1). Pascal's triangle DP works for smaller n without modular arithmetic. Lucas' theorem handles nCr mod p when n is very large but p is small.
Python Template
MOD = 10**9 + 7
def precompute_factorials(n: int) -> tuple[list[int], list[int]]:
"""Precompute factorial and inverse factorial arrays mod MOD."""
fact = [1] * (n + 1)
for i in range(1, n + 1):
fact[i] = fact[i - 1] * i % MOD
inv_fact = [1] * (n + 1)
inv_fact[n] = pow(fact[n], MOD - 2, MOD)
for i in range(n - 1, -1, -1):
inv_fact[i] = inv_fact[i + 1] * (i + 1) % MOD
return fact, inv_fact
def nCr(n: int, r: int, fact: list[int], inv_fact: list[int]) -> int:
if r < 0 or r > n:
return 0
return fact[n] * inv_fact[r] % MOD * inv_fact[n - r] % MOD
def lucas(n: int, r: int, p: int) -> int:
"""nCr mod p for small prime p, using Lucas' theorem."""
if r == 0:
return 1
return lucas(n // p, r // p, p) * nCr_small(n % p, r % p, p) % p
def nCr_small(n: int, r: int, p: int) -> int:
"""Direct nCr mod p for n < p."""
if r < 0 or r > n:
return 0
num = den = 1
for i in range(r):
num = num * (n - i) % p
den = den * (i + 1) % p
return num * pow(den, p - 2, p) % p
Key Edge Cases
nCr(n, 0) = 1 and nCr(n, n) = 1 for all valid nr > n returns 0Common Mistakes
n+1 slots)r > n guard, causing index-out-of-boundsRecognition Signals
Core Idea
Binary exponentiation computes a^b mod m in O(log b) by squaring the base and halving the exponent at each step. Matrix exponentiation extends this: represent a linear recurrence as a matrix multiplication, then raise the transition matrix to the nth power. This turns O(n) recurrence evaluation into O(k^3 log n) where k is the matrix dimension.
Python Template
def power(base: int, exp: int, mod: int) -> int:
"""Binary exponentiation: base^exp mod mod."""
result = 1
base %= mod
while exp > 0:
if exp & 1:
result = result * base % mod
exp >>= 1
base = base * base % mod
return result
Matrix = list[list[int]]
def mat_mul(a: Matrix, b: Matrix, mod: int) -> Matrix:
"""Multiply two square matrices mod mod."""
n = len(a)
result = [[0] * n for _ in range(n)]
for i in range(n):
for k in range(n):
if a[i][k] == 0:
continue
for j in range(n):
result[i][j] = (result[i][j] + a[i][k] * b[k][j]) % mod
return result
def mat_pow(mat: Matrix, exp: int, mod: int) -> Matrix:
"""Raise a square matrix to exp-th power mod mod."""
n = len(mat)
result = [[int(i == j) for j in range(n)] for i in range(n)]
while exp > 0:
if exp & 1:
result = mat_mul(result, mat, mod)
exp >>= 1
mat = mat_mul(mat, mat, mod)
return result
Key Edge Cases
exp = 0: result is 1 (scalar) or identity matrixbase = 0 with exp = 0: conventionally 1, but problem-dependentCommon Mistakes
exp = 0 as a special caseRecognition Signals
Core Idea
Permutations count ordered arrangements; combinations count unordered selections. Stars and bars counts ways to distribute n identical items into k distinct bins: C(n+k-1, k-1). Catalan numbers count structures with recursive nesting (nth Catalan = C(2n, n) / (n+1)). Recognize which formula applies by identifying whether order matters and whether items are identical or distinct.
Python Template
MOD = 10**9 + 7
def permutations_mod(n: int, r: int, fact: list[int], inv_fact: list[int]) -> int:
"""P(n, r) = n! / (n-r)! mod MOD."""
if r < 0 or r > n:
return 0
return fact[n] * inv_fact[n - r] % MOD
def stars_and_bars(n: int, k: int, fact: list[int], inv_fact: list[int]) -> int:
"""Distribute n identical items into k distinct bins (each >= 0)."""
return nCr(n + k - 1, k - 1, fact, inv_fact)
def catalan(n: int, fact: list[int], inv_fact: list[int]) -> int:
"""Nth Catalan number mod MOD."""
return nCr(2 * n, n, fact, inv_fact) * pow(n + 1, MOD - 2, MOD) % MOD
def multiset_coeff(n: int, k: int, fact: list[int], inv_fact: list[int]) -> int:
"""Choose k items from n types with repetition allowed. Uses nCr from above."""
return nCr(n + k - 1, k, fact, inv_fact)
Key Edge Cases
Common Mistakes
n+1 denominator in the Catalan formulaRecognition Signals
Core Idea
Inclusion-exclusion alternates between adding and subtracting intersection sizes: |A1 union A2 union ... Ak| = sum|Ai| - sum|Ai intersect Aj| + .... This is powerful when direct counting is hard but counting elements with specific properties (or their complements) is easy. Derangements are a classic application: D(n) = n! * sum_{i=0}^{n} (-1)^i / i!.
Python Template
MOD = 10**9 + 7
def inclusion_exclusion(sets_sizes: list[int], intersect_fn) -> int:
"""Generic IE over k sets. intersect_fn(mask) returns |intersection of sets in mask|."""
k = len(sets_sizes)
total = 0
for mask in range(1, 1 << k):
bits = bin(mask).count("1")
size = intersect_fn(mask)
if bits % 2 == 1:
total = (total + size) % MOD
else:
total = (total - size + MOD) % MOD
return total
def derangements(n: int) -> int:
"""Count permutations with no fixed points, mod MOD."""
if n == 0:
return 1
if n == 1:
return 0
dp = [0] * (n + 1)
dp[0] = 1
dp[1] = 0
for i in range(2, n + 1):
dp[i] = (i - 1) * (dp[i - 1] + dp[i - 2]) % MOD
return dp[n]
def euler_totient(n: int) -> int:
"""Euler's totient: count integers in [1, n] coprime to n."""
result = n
p = 2
while p * p <= n:
if n % p == 0:
while n % p == 0:
n //= p
result -= result // p
p += 1
if n > 1:
result -= result // n
return result
Key Edge Cases
D(0) = 1 (the empty permutation is a derangement)Common Mistakes
Recognition Signals
Core Idea
The Sprague-Grundy theorem states that every impartial game position has a Grundy number (nimber). A position with Grundy number 0 is a losing position for the player to move. For composite games (independent sub-games), the overall Grundy number is the XOR of individual Grundy numbers. Standard Nim: XOR all pile sizes; if nonzero, first player wins.
Python Template
def compute_grundy(max_state: int, moves_fn) -> list[int]:
"""Compute Grundy numbers for states 0..max_state.
moves_fn(state) returns an iterable of reachable states.
"""
grundy = [0] * (max_state + 1)
for state in range(max_state + 1):
reachable: set[int] = set()
for next_state in moves_fn(state):
reachable.add(grundy[next_state])
mex = 0
while mex in reachable:
mex += 1
grundy[state] = mex
return grundy
def game_winner(values: list[int]) -> str:
"""Winner via XOR. Works for Nim piles or composite Grundy values."""
xor_sum = 0
for v in values:
xor_sum ^= v
return "First" if xor_sum != 0 else "Second"
Key Edge Cases
Common Mistakes
Activates when the user asks about AI prompts, needs prompt templates, wants to search for prompts, or mentions prompts.chat. Use for discovering, retrieving, and improving prompts.
Search, retrieve, and install Agent Skills from the prompts.chat registry using MCP tools. Use when the user asks to find skills, browse skill catalogs, install a skill for Claude, or extend Claude's capabilities with reusable AI agent components.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.