Files
skills/docs/media/image/emblem-solver/src/solver/strip/strip.md
2026-05-29 08:20:56 +01:00

2.1 KiB
Raw Blame History

solver/strip/strip.ts — horizontal/vertical strip decomposition

(no submodules)

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

import { stripDecomposition } from "@suaveplan/emblem-solver/solver";

const required = [
    [true, true, true],
    [true, true, true],
];
const rects = stripDecomposition(required, 2, 3);

Usage: Advanced

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.