fast anagram solver

Steampunk-style mechanical anagram solver transforming old words into new words

exact, subset, and multi‑word phrases. completely private, all computation in browser.

examples: dormitory astronomer listen santa
advanced options
worker pushes progress; typed arrays are transferred, not copied.
wildcards: include ? in the letters box; they cover any deficit.
performance: we index once, then queries are fast. phrases stop at a solution/time cap to stay snappy.
caching: dictionary is permanently cached in IndexedDB. first load downloads once; every subsequent visit is instant.
loading dictionary…
results:
how it works (short)

three related problems, three slightly different hammers:

  1. exact anagrams (single word) — compute a word’s signature (letters sorted). all words with the same signature are mutual anagrams. O(1) map lookup.
  2. subset anagrams (single word) — 26‑bit presence mask rejects non‑candidates, then a 26‑byte counts check (with wildcards) verifies multiplicities.
  3. phrases (many words) — prefilter with mask+counts, then a bucketed dfs that always pivots on the rarest remaining letter. we track used candidates and normalize each phrase so permutations collapse; optional memoization still prunes repeated dead states.

we keep data in typed arrays for cache‑friendliness; the heavy indexing runs in a web worker.

svg diagram of the pipeline
anagram solver pipeline data and control flow for exact, subset, and phrase anagram modes, including indexes and pruning steps. input letters + ? wildcards normalize strip accents, a–z only mode exact (single word) signature = sorted letters O(1) map lookup → matches subset (single word) mask reject: (wordMask & ~rackMask) ≠ 0 ➜ drop counts check ≤ rack + ? optional: score + sort phrase (multi‑word) prefilter with mask+counts buckets: letter → candidates dfs with rare‑letter pivot used-set + normalized signature dedupe memoization (optional) indexes (built once, in worker) masks: Uint32Array(N) counts: Uint8Array(N×26) scores: Uint16Array(N) signature map: Map(signature → [i…]) built from dictionary once web worker builds indexes, streams progress
the dashed box is the one‑time index build (done off the main thread). arrows show which index each mode touches.
deep dive — why these choices

think of the dictionary as a field of tall grass. we don’t mow it; we lay narrow paths: