first commit
This commit is contained in:
64
docs/media/image/emblem-solver/src/solver/strip/strip.md
Normal file
64
docs/media/image/emblem-solver/src/solver/strip/strip.md
Normal file
@@ -0,0 +1,64 @@
|
||||
# `solver/strip/strip.ts` — horizontal/vertical strip decomposition
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
This module implements `stripDecomposition`, a complementary cover strategy
|
||||
that ignores the maximal-rect candidate pool entirely. It finds maximal
|
||||
horizontal runs of required pixels, merges vertically-adjacent runs that
|
||||
share both `x` and `length`, and runs the transposed variant (vertical runs
|
||||
merged horizontally). The smaller of the two orientations wins. This
|
||||
strategy is what gives `convert()` the right answer on tall thin shapes
|
||||
that the histogram + greedy combo fragments.
|
||||
|
||||
## Features
|
||||
|
||||
- O(rows × cols) per axis; tail-call-free `while` loops.
|
||||
- Two orientations evaluated, smaller wins — deterministic.
|
||||
- Produces non-overlapping rects (unlike the overlap optimiser); the layer
|
||||
pipeline only adopts the strip result if it covers the entire required
|
||||
mask, otherwise it falls back to the greedy cover.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { stripDecomposition } from "@suaveplan/emblem-solver/solver";
|
||||
|
||||
const required = [
|
||||
[true, true, true],
|
||||
[true, true, true],
|
||||
];
|
||||
const rects = stripDecomposition(required, 2, 3);
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
import {
|
||||
stripDecomposition,
|
||||
isFullyAvailable,
|
||||
} from "@suaveplan/emblem-solver";
|
||||
|
||||
const strips = stripDecomposition(required, rows, cols);
|
||||
const valid = strips.filter((r) => isFullyAvailable(r, available));
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
| Symbol | Kind | Description |
|
||||
|---|---|---|
|
||||
| `stripDecomposition(required, rows, cols)` | fn | Smaller of horizontal-strips / vertical-strips |
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
`mergeRuns` sorts runs by their primary coordinate, then their length, then
|
||||
their secondary coordinate. The merge loop walks the sorted list once and
|
||||
collapses consecutive entries that share `(x, length)` (horizontal) or
|
||||
`(y, length)` (vertical) into a single taller/wider rect. Because the sort
|
||||
is stable on JavaScript's `Array.prototype.sort` and we break on a length
|
||||
mismatch, the merge terminates in O(n). The dual-orientation evaluation
|
||||
ensures we never make the cover worse by picking the wrong axis — the
|
||||
chess-board test exercises this branch heavily.
|
||||
Reference in New Issue
Block a user