High-performance mathematical computation tools.
| Project | Description | Implementation | CI |
|---|---|---|---|
pi/ |
Calculate π to N decimal places | Python + Rust | |
prime/ |
Find all primes up to 10^N | Rust | |
fib/ |
Generate all Fibonacci numbers with up to 10^X digits | Python + Rust | |
sq/ |
Generate all perfect squares with up to 10^N digits (N=1 max) | Python + Rust | |
twin-primes/ |
Find all twin prime pairs up to 10^N | Rust | |
e/ |
Calculate e to N decimal places | Python + Rust | |
factorial/ |
Compute N! to arbitrary precision (prime swing algorithm) | Python + Rust | |
perfect-numbers/ |
Find all perfect numbers up to 10^N (Lucas-Lehmer + sigma) | Python + Rust | |
collatz/ |
Find Collatz chain record-setters up to 10^N | Python + Rust | |
goldbach/ |
Find all Goldbach pairs for even numbers up to 10^N | Rust | |
amicable/ |
Find all amicable pairs (a,b) with b ≤ 10^N (proper-divisor sum sieve) | Python + Rust |
| CLI | Python | Rust |
|---|---|---|
| amicable | ||
| collatz | ||
| e | ||
| factorial | ||
| fib | ||
| goldbach | — | |
| perfect-numbers | ||
| pi | ||
| prime | — | |
| sq | ||
| twin-primes | — |
Calculates π to an arbitrary number of decimal places using the Chudnovsky algorithm with binary splitting.
- Python implementation (
pi/pi.py) — best for up to ~50M digits - Rust implementation (
pi/pi-rs/) — best for 50M+ digits; shared-memory rayon parallelism with zero IPC overhead
See pi/README.md for full details.
Finds every prime number up to 10^N using a parallel segmented Sieve of Eratosthenes.
- Rust implementation (
prime/prime-rs/) — packed bitset segments (32 KB each, fits in L2 cache), rayon-parallelised across all cores, streams output to file to keep peak RAM ≤ ~50 MB
See prime/README.md for full details.
Generates every Fibonacci number with at most 10^X decimal digits.
- Python implementation (
fib/fib.py) — uses Python's built-in arbitrary-precisionint; no external dependencies - Rust implementation (
fib/fib-rs/) — usesrug/GMP for best performance at large digit counts
See fib/README.md for full details.
Generates every perfect square with at most 10^N decimal digits. N=1 is the only valid value (produces 99,999 squares up to 10 digits).
- Python implementation (
sq/sq.py) — Python stdlib only, no external dependencies - Rust implementation (
sq/sq-rs/) — plain u64 arithmetic, no GMP required
See sq/README.md for full details.
Finds every twin prime pair (p, p+2) where both primes are less than 10^N.
- Rust implementation (
twin-primes/twin-primes-rs/) — packed bitset segments (32 KB each, fits in L2 cache), constant memory usage regardless of N
See twin-primes/README.md for full details.
Calculates Euler's number e to an arbitrary number of decimal places using the Taylor series with binary splitting.
- Python implementation (
e/e.py) — gmpy2/GMP fast path with mpmath fallback - Rust implementation (
e/e-rs/) — shared-memory rayon parallelism with zero IPC overhead
See e/README.md for full details.
Computes N! (N factorial) to arbitrary precision using the prime swing algorithm (n! = swing(n) × (⌊n/2⌋!)²).
- Python implementation (
factorial/factorial.py) — gmpy2/GMP fast path with plain int fallback; parallel swing viaProcessPoolExecutor - Rust implementation (
factorial/factorial-rs/) —rug/GMP with rayon parallel chunks
See factorial/README.md for full details.
Finds all perfect numbers up to 10^N using the Lucas-Lehmer primality test (even perfect numbers via Mersenne primes) and a sigma divisor-sum sieve (odd perfect numbers, none known but checked for completeness).
- Python implementation (
perfect-numbers/perfect_numbers.py) — pure Python stdlib, no external dependencies - Rust implementation (
perfect-numbers/perfect-numbers-rs/) —rug/GMP for arbitrary-precision sigma computation
See perfect-numbers/README.md for full details.
cd pi
make run # python3 pi.py
make lint # ruff check . && ruff format --check .
make test # lint, then pytest test_pi.py -v
make coverage # pytest --cov=pi --cov-report=term-missingcd pi/pi-rs
make pi # cargo build --release
make lint # cargo fmt --check, then cargo clippy --all-targets -- -D warnings
make test # lint, then cargo testcd prime/prime-rs
make prime # cargo build --release
make lint # cargo fmt --check, then cargo clippy --all-targets -- -D warnings
make test # lint, then cargo testcd fib
make run # python3 fib.py
make lint # ruff check . && ruff format --check .
make test # lint, then pytest test_fib.py -v
make coverage # pytest --cov=fib --cov-report=term-missingcd fib/fib-rs
make fib # cargo build --release
make lint # cargo fmt --check, then cargo clippy --all-targets -- -D warnings
make test # lint, then cargo testcd sq
make run # python3 sq.py
make lint # ruff check . && ruff format --check .
make test # lint, then pytest test_sq.py -v
make coverage # pytest --cov=sq --cov-report=term-missingcd sq/sq-rs
make sq # cargo build --release
make lint # cargo fmt --check, then cargo clippy --all-targets -- -D warnings
make test # lint, then cargo testcd twin-primes/twin-primes-rs
make twin-primes # cargo build --release
make lint # cargo fmt --check, then cargo clippy --all-targets -- -D warnings
make test # lint, then cargo testcd e
make run # python3 e.py
make lint # ruff check . && ruff format --check .
make test # lint, then pytest test_e.py -v
make coverage # pytest --cov=e --cov-report=term-missingcd e/e-rs
make e # cargo build --release
make lint # cargo fmt --check, then cargo clippy --all-targets -- -D warnings
make test # lint, then cargo testcd factorial
make run # python3 factorial.py
make lint # ruff check . && ruff format --check .
make test # lint, then pytest test_factorial.py -v
make coverage # pytest --cov=factorial --cov-report=term-missingcd factorial/factorial-rs
make factorial # cargo build --release
make lint # cargo fmt --check, then cargo clippy --all-targets -- -D warnings
make test # lint, then cargo testcd perfect-numbers
make run # python3 perfect_numbers.py
make lint # ruff check . && ruff format --check .
make test # lint, then pytest test_perfect_numbers.py -v
make coverage # pytest --cov=perfect_numbers --cov-report=term-missingcd perfect-numbers/perfect-numbers-rs
make perfect-numbers # cargo build --release
make lint # cargo fmt --check, then cargo clippy --all-targets -- -D warnings
make test # lint, then cargo testcd collatz
make run # python3 collatz.py
make lint # ruff check . && ruff format --check .
make test # lint, then pytest test_collatz.py -v
make coverage # pytest --cov=collatz --cov-report=term-missingcd collatz/collatz-rs
make collatz # cargo build --release
make lint # cargo fmt --check, then cargo clippy --all-targets -- -D warnings
make test # lint, then cargo testcd goldbach/goldbach-rs
make goldbach # cargo build --release
make lint # cargo fmt --check, then cargo clippy --all-targets -- -D warnings
make test # lint, then cargo testcd amicable
make run # python3 amicable.py
make lint # ruff check . && ruff format --check .
make test # lint, then pytest test_amicable.py -v
make coverage # pytest --cov=amicable --cov-report=term-missingcd amicable/amicable-rs
make amicable # cargo build --release
make lint # cargo fmt --check, then cargo clippy --all-targets -- -D warnings
make test # lint, then cargo testFinds Collatz chain record-setters up to 10^N using vector memoization.
- Python implementation (
collatz/collatz.py) — stdlib only, practical for N≤7 - Rust implementation (
collatz/collatz-rs/) —Vec<u32>memoization, handles N≤9 comfortably
See collatz/README.md for full details.
Finds all Goldbach pairs for even numbers up to 10^N.
- Rust implementation (
goldbach/goldbach-rs/) — packed bitset sieve, BufWriter streaming, practical up to N=6 (~20 GB output)
See goldbach/README.md for full details.
Finds all amicable pairs (a, b) where a < b ≤ 10^N using a proper-divisor sum sieve (sigma function over all numbers up to the limit, then cross-checking pairs).
- Python implementation (
amicable/amicable.py) — stdlib only, no external dependencies - Rust implementation (
amicable/amicable-rs/) — plain u64 arithmetic with a pre-computed sigma sieve
See amicable/README.md for full details.
After cloning, install the git hooks and root-scope Python dependencies:
make install-hooks # symlinks pre-commit, pre-push and commit-msg
make install-deps # installs what tests/, scripts/ and .claude/scripts/ importinstall-deps reads requirements-dev.txt — the third-party modules root-scope
Python actually imports (defusedxml, pyyaml), not a tool list. It refuses on a
PEP 668 externally-managed interpreter rather than using --break-system-packages,
and the refusal names the remedy: python3 -m venv .venv && . .venv/bin/activate.
Without it, make test fails at import — scripts/pre-push runs the root suite on
any push touching scripts/, tests/ or .claude/scripts/.
install-hooks symlinks scripts/pre-commit into .git/hooks/pre-commit. The hook runs make lint on staged sub-projects and scans for secrets with ggshield (skipped gracefully if not installed). CI secret-scan via gitleaks is a backstop — local scanning catches secrets before they leave the machine.
Install ggshield: brew install gitguardian/tap/ggshield && ggshield auth login.
brew install git-cliff— CHANGELOG generation (make changelog)
Rust crates use scripts/rust-check.sh for make lint and make test. By default it sets CARGO_HOME to a repo-local writable cache path and can run offline when dependencies are cached:
RUST_CHECK_OFFLINE=1 make testEvery Rust sub-project also has make bench (Criterion benchmarks). CI alerts when any benchmark regresses more than 30% vs the previous run. cargo test includes CLI integration tests from tests/cli.rs alongside the unit tests.
Python CI runs two additional quality steps per sub-project: pyright (static type checking) and pip-audit (dependency security scan). These run in CI only — there is no local make target for them. Run them manually with pyright and pip-audit from the sub-project directory.
Key decisions are recorded in docs/adr/: algorithm choices (Chudnovsky, segmented sieve), language strategy (Python vs Rust), library choices (GMP/rug, rayon), and CI structure.
Release binaries are signed with cosign using keyless Sigstore signing. Each release includes the binary plus:
{name}.sha256— SHA256 checksum{name}.sbom.spdx.json— SPDX bill of materials{name}.bundle— cosign signature bundle (v4 format; supersedes the separate.sig/.pempair)
To verify a release binary (example for factorial):
cosign verify-blob factorial \
--bundle factorial.bundle \
--certificate-identity \
"https://github.com/brujack/math/.github/workflows/release-factorial-rs.yml@refs/heads/master" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"Replace factorial with the sub-project name (e.g. fib), and release-factorial-rs.yml with that
sub-project's own release workflow filename (e.g. release-fib-rs.yml) — the certificate identity is
the workflow that requested the signing certificate, not the tag being released. No release has been
cut with this pipeline yet, so treat the identity above as derived from how keyless signing works
rather than observed — read it back from a real release's own .bundle to confirm it before relying
on it.