Move docs/ package mirror into document-navigator plugin
Relocate the ~6k-file docs tree from the repo root into plugins/document-navigator/docs/ so the plugin is self-contained and portable. docs/superpowers/ (specs and plans) stays at the repo root. Moved via cp+rm rather than git mv because directory rename() fails with EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the identical-content files at commit time. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
# `helpers/helpers.ts` — packing, keys, and grid primitives
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
This module is the shared kernel of utility functions used by the analyser,
|
||||
the solver strategies, and the optimisers. It owns the canonical
|
||||
representation of a pixel index (a packed `y * width + x` integer), the
|
||||
canonical colour key (`"r,g,b"`), the `computeBounds` reduction over a
|
||||
packed-pixel set, and the boolean-grid builders that drive the
|
||||
maximal-rectangle sweep and per-layer covering.
|
||||
|
||||
## Features
|
||||
|
||||
- `pack` / `unpackX` / `unpackY` give the package a single, branch-free way
|
||||
to convert between `(x, y)` and a single integer. Using a `Set<number>`
|
||||
of packed indices is dramatically cheaper than a `Set<string>` of
|
||||
`"x,y"`.
|
||||
- `colourKey` / `parseKey` round-trip an RGBA without committing to alpha;
|
||||
the solver does not need alpha for keying.
|
||||
- `computeBounds` is the only place we touch unpack-loop machinery for
|
||||
bounds computation; everywhere else delegates here.
|
||||
- `isFullyAvailable`, `rectCoversAnyRequired`, and `countRequired` are the
|
||||
three predicates the optimiser relies on; they share an early-exit
|
||||
pattern that keeps the solver O(area × candidates) rather than
|
||||
O(area² × candidates).
|
||||
- `buildAvailableGrid` / `buildRequiredGrid` allocate the 2-D `boolean[][]`
|
||||
masks used by the cover strategies.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { pack, unpackX, unpackY } from "@suaveplan/emblem-solver";
|
||||
|
||||
const w = 8;
|
||||
const idx = pack(3, 2, w); // 19
|
||||
unpackX(idx, w); // 3
|
||||
unpackY(idx, w); // 2
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
import {
|
||||
buildAvailableGrid,
|
||||
buildRequiredGrid,
|
||||
isFullyAvailable,
|
||||
} from "@suaveplan/emblem-solver";
|
||||
|
||||
const opaque = new Set<number>([0, 1, 2, 3]);
|
||||
const earlier = new Set<number>();
|
||||
const avail = buildAvailableGrid(2, 2, opaque, earlier);
|
||||
const req = buildRequiredGrid(opaque, 2, 2);
|
||||
isFullyAvailable({ x: 0, y: 0, w: 2, h: 2 }, avail); // true
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
| Symbol | Kind | Description |
|
||||
|---|---|---|
|
||||
| `pack(x, y, w)` | fn | Row-major packed index |
|
||||
| `unpackX(i, w)` | fn | Recover `x` |
|
||||
| `unpackY(i, w)` | fn | Recover `y` |
|
||||
| `colourKey(rgba)` | fn | `"r,g,b"` |
|
||||
| `parseKey(str)` | fn | `RGBA` with `a:1` |
|
||||
| `computeBounds(set, w)` | fn | Tight bounding `Rect` |
|
||||
| `isFullyAvailable(rect, grid)` | fn | All cells `true`? |
|
||||
| `rectCoversAnyRequired(rect, req)` | fn | Any overlap? |
|
||||
| `countRequired(rect, req)` | fn | Overlap count |
|
||||
| `buildAvailableGrid(w, h, opaque, earlier)` | fn | 2-D opaque mask minus earlier layers |
|
||||
| `buildRequiredGrid(set, w, h)` | fn | 2-D mask from packed pixel set |
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The functions are deliberately monomorphic over `boolean[][]`/`number` for
|
||||
predictable JIT performance. The bounding-box reduction uses `±Infinity`
|
||||
sentinels so it works for any non-empty set. The available-grid builder
|
||||
skips earlier-layer pixels in O(1) per packed index — important when the
|
||||
solver iterates orderings exhaustively over a colour set. None of these
|
||||
helpers allocate beyond the grids they explicitly build; the predicates
|
||||
return as soon as their early-exit condition is met, so worst-case work is
|
||||
bounded by `rect.w * rect.h`.
|
||||
Reference in New Issue
Block a user