Add regex engine, edit distance, and Bloom filter playgrounds - #204
Merged
Conversation
Three playgrounds in domains the site did not yet cover: automata and compilers, dynamic programming, and probabilistic data structures. - /regex src/features/regex/engine.ts Pattern -> syntax tree -> NFA (Thompson's construction) -> DFA (subset construction), then a linear-time non-backtracking walk. Verified differentially against JavaScript's own RegExp: 460 curated cases plus 5,200 randomly generated pattern/input pairs, zero mismatches. - /editdistance src/features/editdistance/levenshtein.ts Wagner-Fischer DP with per-cell provenance and traceback. Verified against 10 textbook distances (kitten->sitting=3, intention->execution=5), the metric axioms over 300 random triples, length bounds, and 400 traceback round-trips where applying the recovered edit script to the source reproduces the target at exactly the stated cost. - /bloom src/features/bloom/bloom.ts Bit array with k derived hashes, plus the closed-form false-positive rate and optimal-sizing helpers. Verified: never a false negative, empty rejects everything, saturated accepts everything, and the measured false-positive rate tracks the theoretical formula. Testing caught a real bug here. Raw FNV-1a mixes its low bits poorly and bucket selection is hash % m, which reads exactly those bits, so the filter collided in structured ways: chi-square 1335 against df=1023, fill 29% below theory, and false-positive rates 2-3x off. Adding a MurmurHash3 fmix32 avalanche step brings chi-square to 1016, fill within 1.9% of theory, and the false-positive rate within 9% of the formula. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WgEKRuVdor8KhaiPkv38aQ
✅ Deploy Preview for ianalloway ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
ianalloway
marked this pull request as ready for review
July 27, 2026 02:14
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three playgrounds in domains the site didn't yet cover: automata/compilers, dynamic programming, and probabilistic data structures. Consolidated into one PR per the new convention.
/regex/editdistance/bloomHow each was verified
/regex— parses to a syntax tree, compiles to an NFA by Thompson's construction, determinises by subset construction, then walks the DFA with no backtracking (linear time). Verified differentially against JavaScript's ownRegExp: 460 curated cases plus 5,200 randomly generated pattern/input pairs — zero mismatches. The classic(a|b)*abbcompiles to 14 NFA states → 5 DFA states./editdistance— Wagner–Fischer with per-cell provenance so the traceback recovers an actual edit script. Verified against 10 textbook distances (kitten→sitting = 3, intention→execution = 5), the metric axioms over 300 random triples (symmetry, identity, triangle inequality), length bounds, and 400 traceback round-trips where applying the recovered script to the source reproduces the target at exactly the stated cost./bloom— bit array with k derived hashes, plus closed-form FPR and optimal-sizing helpers. Verified: never a false negative, empty rejects everything, saturated accepts everything, sizing for a 1% target measures 0.94%.A real bug this caught
The Bloom filter initially looked better than theory — false-positive rates 2–3× below the formula. That's not luck, it's a symptom. Raw FNV-1a mixes its low bits poorly, and bucket selection is
hash % m, which reads exactly those bits:Adding a MurmurHash3
fmix32avalanche finalizer fixed all three. Worth noting because a filter that quietly under-collides would have looked perfectly fine on screen.Checks
npm run lint— 0 errors (only the two pre-existingreact-refreshwarnings inbadge.tsx/button.tsx)npm run build— succeeds; all three pages confirmed to emit their own lazy chunkOne note on the diff: the Bloom page originally held the filter in a
useRefand rebuilt it in an effect, which trippedreact-hooks/refs(reading a ref during render). Since the filter is fully determined by(k, addedWords)it's now auseMemo— simpler and correct by construction rather than by discipline.🤖 Generated with Claude Code
https://claude.ai/code/session_01WgEKRuVdor8KhaiPkv38aQ
Generated by Claude Code