Feat/other algorithms#26
Merged
Merged
Conversation
…rithms Adds two reusable viz primitives and wires 7 algorithms from the 'misc' category: NumberLab (small-math register tape + formula card + history strip): - fibonacci-iterative (rolling two-value window with F(0)..F(n) history) - factorial (accumulator multiply with per-k history) - euclidean-gcd (remainder + swap with pair history) PointerLab (cell row + pointer markers + window overlay + stats strip): - two-pointers (pair-sum search with directional shrink decisions) - sliding-window (fixed window max-sum tracker) - palindrome-check (symmetric two-pointer scan) - reverse-string-array (in-place swap reversal) Each algorithm ships generator + structured code + preset scenarios + EN/PL i18n for phases, descriptions, decisions, registers, stats, and scenario labels. Shared NumberLab / PointerLab trace panels expose facts, calc, streams, and stats tiles. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…gorithms Adds two new reusable viz primitives and wires 3 more algorithms from the 'misc' category. Kadane is routed through the existing PointerLab primitive since its state shape (array + current window + best window + stats) is a clean subset of the pointer-lab model. SieveGrid (responsive number grid + pivot strip + factor annotations): - sieve-of-eratosthenes: cells tint from unchecked → current prime → crossed composite; factor labels (×k) fade in while marking; the active prime p stays pinned in the header with √n bound and live primes count. CallStackLab (stack column + return rail + call stats): - recursion-call-stack (naive recursive Fibonacci): frames animate in/out with per-phase tones (descend-left, descend-right, combine, return); return values flash before popping; a breadcrumb rail retains the last few pops with fading opacity so the unwind is visible at a glance. Kadane (reuses PointerLab): - Four presets — classic signed mix, lone spike in noise, all-negative least-bad pick, and zigzag — each crafted to fire a different mix of extend vs. restart decisions. Window tone flips to "best" whenever current sum overtakes the record, holding it until beaten again. Each algorithm ships generator + structured code + preset scenarios + full EN/PL i18n for phases, descriptions, decisions, and stats. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…rithms Adds a new reusable primitive for algorithms that build an explicit decision tree and wires 3 more algorithms from the 'misc' category. All three share the same tree layout (reusing the existing Reingold–Tilford util) but pick their own node metadata and per-phase tones. CallTreeLab (responsive tree canvas + SVG edge layer + HTML node cards): - Reingold–Tilford layout with curved edges + active-path highlight - Per-node cards hold title + subtitle + stat chips + phase badge - Optional sidecar board for algorithms with a physical state view - Phases: pending / exploring / explored / current / solution / conflict / pruned / backtracked — each tinted so the tree reads at a glance Backtracking (N-Queens, uses CallTreeLab + chess-board sidecar): - 4/5/6-queens presets; board tints placed queens, attacked cells, the current probe, and conflicts; tree nodes carry row/col and badges: ✓ solution, ✗ conflict, ↶ backtracked Minimax with α/β pruning: - Node cards show (α, β, value) as chips; pruned siblings render as dashed placeholder cards tagged "cut"; stats track evaluated vs pruned leaf count so the savings from pruning are legible - 3 presets: balanced 2×3, prunable 3×2 (classic textbook tree), wide 3×3 for heavier pruning Monte Carlo Tree Search (UCB1): - Explicit 4-phase cycle: select → expand → simulate → backprop; each phase gets its own tone + description; nodes carry N (visits) / μ (mean reward) / UCB, and the current path glows root→leaf - Deterministic leaf rewards per preset so the trace is reproducible - Best-arm callout updates each backprop; final step highlights the most-visited child Each algorithm ships generator + structured code + preset scenarios + full EN/PL i18n for phases, descriptions, decisions, and stats. Also: gitignore .claude runtime dir so ScheduleWakeup lock files stop leaking into commits. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wrapped KaTeX in a reusable math-text renderer and tuned it for multiple UI contexts across the app, including cards, info panels, tags, tables, visualizations and now logs. The renderer now supports mixed text-plus-math content, so Transloco strings can interpolate dynamic values and still mark inline formulas explicitly instead of forcing whole log lines into math mode. Log entries keep their technical monospace character, but math fragments like fib(n), gcd(...), n!, p², alpha/beta and similar notation are rendered with clearer emphasis and better on-screen readability.
Lifts inconsistencies between visualization stats, cell values, and
trace panels now that the core math-text pipeline is in place. Keeps
the same KaTeX font family across every numeric / symbolic label, adds
a new `cell` variant for dense grids, and closes a few bugs in the
macro-termination logic that the previously-unreachable test suite
surfaced once it started running.
math-text pipeline:
- New `cell` variant (scale 1, zero glow/tracking) for dense grids that
need KaTeX typography but no visual bump.
- Module-level LRU cache (512 entries) around `katex.renderToString`
keeps long log playbacks cheap.
- `looksMathishContent` now treats bare integers and decimals as
math — resolves the sieve "14" (mono) vs palindrome "a" (KaTeX
sans) mismatch that showed when both rendered side by side.
- Symbol map grows with Stage-4 operators (≠, ≡, ∈, ∉, ∪, ∩, ⊂, ⊆,
⌊, ⌋, ⌈, ⌉) and UCB1 → \mathrm{UCB}_{1}.
- UCB macro ordering flipped so UCB1 no longer ends up double-wrapped
as \mathrm{\mathrm{UCB}}_{1}.
- Post-pass inserts a space between bare TeX macros and following
alphanumeric tokens (split in two: digit-after for all whitelisted
macros; letter-after only for bracket macros where the shape is
unambiguous — `\left` no longer gets cut into `\le ft`).
Visualization coverage:
- pointer-lab cell values, stats, result.
- call-stack-lab stats, frame.returnValue, locals, rail value, depth.
- sieve-grid pivot label/value, √n, stats, cell value, factor, result.
- number-lab register value, history chip value.
- call-tree-lab node-stat sizing toned metric→chip/cell; top stats
toned metric→formula; sidecar title + footer now go through
math-text.
Vitest config:
- `include` now picks up `src/app/shared/**/*.spec.ts`. The existing
math-text.utils.spec.ts was silently excluded before, which let the
`\cdot2`, UCB double-wrap, and `⌊n/2⌋` regressions live in the
code without tests catching them. Three new assertions cover plain-
number detection, UCB1 subscript, and Stage-4 operator mapping.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…clidean GCD
Builds a "tablica" visualization primitive designed for math-heavy
algorithms where the register dashboard answers "what is in memory"
but not "why — what's the derivation we're following." Starts with
Euclidean GCD as the pilot; the same primitive will carry Fibonacci,
Factorial, Extended Euclidean, Miller-Rabin, CRT, and the rest of the
Stage 4 number-theory lineup.
ScratchpadLab primitive:
- `ScratchpadLine` model with kinds (goal / note / equation /
substitute / decision / result / divider), per-line `caption`
(frozen step title), `instruction` (imperative tag), `annotation`
(numeric result) and state (current / settled) so lines enter in
time with playback and settle into a calmer tone as newer ones
arrive.
- Chalkboard / notebook aesthetic: Caveat handwriting font for
narrative chrome (goal, captions, decisions, instructions, sticky
notes, signoff) paired with mono/KaTeX for the math itself.
Per-line dashed guides replace the canvas-wide ruling so the eye
can track body → annotation on long derivations.
- Cascading indents on substitute lines so the derivation reads as
a nested block under the opening equation the way a student would
write it on paper — `= gcd(b, r)` hangs under `gcd(a, b)`.
- Section-level markers (① start, ② decision, ✓ result) instead of
numbering every line; long derivations don't drown in ordinals.
- Global + per-line margin sticky notes for invariants and transient
"upcoming" hints during mid-compute steps.
- Viz-options-menu (gear icon) with checkboxes for "Show step titles"
and "Show instructions", persisted to localStorage so students keep
their preferred density across sessions.
Euclidean GCD flow:
- Generator emits both `numberLab` (dashboard) and `scratchpadLab`
(chalkboard) trace states per step so the variant toggle is
instantaneous — no engine reset required.
- Scratchpad preamble writes out the goal, the algorithm rule, and
the initial pair; each iteration appends a substitute line with an
imperative tag ("Compute 48 mod 36") and the numeric annotation
("48 mod 36 = 12").
- Terminal case appends the decision line ("b = 0 → stop, gcd = a")
and the boxed result in one coherent block.
- Variant toggle defaults to Chalkboard for Euclidean; dashboard
stays available via the toolbar variant picker.
Shared `<app-viz-options-menu>`:
- Gear trigger + anchored popover, closes on outside click / Esc.
- Controlled component — parent owns option state and handles
persistence. Ready to be adopted by future viz variants that want
per-viz density / display toggles.
i18n: EN + PL strings for mode labels, captions, phases, decisions,
sticky notes, option labels + descriptions, shared gear aria labels.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Extended Euclidean is the first proper stress test of the ScratchpadLab primitive — it has a forward division chain AND a back-substitution phase, both of which a textbook walks a student through on a physical chalkboard. The dashboard view has nothing useful to add here, so we expose only the chalkboard variant. Generator: - Phase 1 collects every `a = q·b + r` forward equation as its own scratchpad line (kind: equation), with `a mod b = r` in the annotation and an imperative "Divide a by b" instruction chip. - Transition line `gcd = N` (kind: decision, marker ⟹) separates the two phases with a visual divider above it. - Phase 2 carries a running `gcd = coefOfU · u + coefOfV · v` expression and emits one substitute line per rewrite. The coefficient bookkeeping is worked out carefully so the back-sub chain terminates with the correct Bézout pair (s, t) regardless of parity of substitutions. - Final signoff boxes the result `gcd = s·a + t·b` and the numeric verification lands in the annotation of the decision line above it. Scenarios (three presets): - short — gcd(60, 48), one-step back-sub for a first Bézout. - classic — gcd(240, 46), five forward steps fold into a four-layer back-sub. Textbook choice. - large — gcd(1071, 462), mirrors the Euclidean "large" preset so the student can watch the Bézout derivation on a chain they already recognise. Wiring: - EXTENDED_EUCLIDEAN_VIEW_CONFIG with kind: 'number-lab' (reuses the existing (a, b) scenario dispatch) but SCRATCHPAD_LAB_ONLY_VARIANT_ OPTIONS so the dashboard toggle is hidden. - Section markers ① (forward seed) ⟹ (gcd) ② (back-seed) ③ (verify) ✓ (result) match the Euclidean style. - Catalog: implemented: true, complexity O(log min(a, b)) for time and space. i18n (EN + PL): goal, rule, invariant, all forward/back/result lines, captions (8), phases (6), decisions (7), scenario presets. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Euclidean GCD and Extended Euclidean both drive their input via scenario chips in the viz header; the toolbar's "dataset size" select carried a [1, 2, 3] placeholder only because the config interface requires it, and the createScenario functions ignore the size parameter entirely. Students clicked the select, watched nothing happen, and concluded the scenario picker was broken. Matches the existing `hasVariantChoice` pattern: hide the control when there's no meaningful choice rather than surface a no-op dropdown. - visualization-toolbar: new `hasSizeChoice` computed mirrors the variant-choice guard. Template wraps the size lab-select in `@if (hasSizeChoice())`. - Euclidean GCD and Extended Euclidean configs: collapse `sizeOptions` to `[1]` so the toolbar hides the select automatically. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pins stack (Angular 21 signals, standalone, OnPush, strict TS, no-comments), design-system tokens, visualization architecture (Generator<SortStep>, VisualizationRenderer, scratchpad primitive), i18n discipline, and branch/release flow so Claude Code sessions in this repo start with full project grounding. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds eight ohno-* skills covering visualization anatomy, algorithm step generators, design tokens, scratchpad/chalkboard narrative, motion + a11y, i18n discipline, UX principles, and the viz polish checklist, plus an ohno-design-reviewer agent for read-only audits. Updates .gitignore so .claude/skills/ and .claude/agents/ are versioned with the repo while .claude/settings.local.json stays private per-dev. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Codifies a standing user preference: when a task touches UI, visualization, tokens, or shared component code, Claude must emit an ALL-CAPS reminder (between horizontal rules, in the final turn) to dispatch the ohno-design-reviewer agent before committing. Lists explicit triggers and exclusions so the rule fires where it matters and stays quiet for pure-logic changes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
In long multi-day sessions, project rules can drift out of top-of-mind even when the file is still loaded in context. The new "Context hygiene" section instructs Claude to re-read CLAUDE.md at the start of each new logical task, re-read relevant skills when triggered, and stop to verify the file (rather than guess) on any rule uncertainty. Cheap belt-and-suspenders against behavioral drift. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…uto-scroll Three passes on the chalkboard view for Euclidean GCD + Extended Euclidean after pedagogical review: - Pedagogical: forward instruction teaches the equation shape (`Rozpisz a = q·b + r`) rather than an ambiguous "divide". Imperative chips no longer linger on lines that already show the computed result — chip is transient during compute, annotation records the derivation on the settled line. Captions follow the cursor. Viewport auto-scrolls to the active line on long derivations. - Structural polish: result box loses the UI-button halo, annotation column leads with a cursive `∴` instead of a parallel mono column, GCD's stop-decision marker (`②`) unifies with EEA as `⟹` so the number-theory family shares one glyph alphabet, transient margin and persistent instruction chip speak the same warm-tan colour. - Typography pivot: walked back Caveat cursive. At ultrawide / high-DPI scales it was reading as Figma-mockup-cheap. `--font-notebook` now points at Newsreader italic — screen-optimised serif that carries a Tufte-style margin-note voice without the uncanny-valley feel of artificial handwriting. Docs (CLAUDE.md, ux-principles, scratchpad-narrative, design-tokens skills) updated to reflect the editorial direction. Spec lives under docs/superpowers/specs/ for the rationale trail. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two refinements to how the chalkboard surfaces past state once an algorithm has moved on from a line: - Hover on settled lines now paints a soft warm wash (viz-warning @ 5.5% alpha) plus a 2px inset accent on the left. Current/result rows already own a distinct surface, so hover skips them; goal/rule header block skips it too (hovering the thesis makes no sense). Transitions disabled under prefers-reduced-motion. - `ScratchpadLine` gains an optional `captionPinned` flag. Default behaviour (caption visible on current line only) still holds for loop-body rows where the caption repeats — middle forward rows, substitute iterations, back-sub steps. Phase-entry captions — goal, first forward row, terminal forward row, gcd announce, back-seed, verify, result — set it true so the narrative anchor persists on settled lines too. The viz-options "Show step titles" toggle still gates the whole behaviour. Net effect: long derivations read like an annotated scroll with chapter markers instead of a timestamp feed, and the student can hover back to any past line to pull it gently into focus. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Hover rule painted a 5.5%-alpha wash onto rows that already sit at opacity 0.82 — the compounded ~4% read barely crossed the noise floor. Bump the alphas and, more importantly, reset opacity to 1 on hover so the row actively "pulls into focus" from its past-state dimming. Skip still applies to goal/rule/current/result. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Moves the "what problem are we solving / with what numbers" axis out of eight per-viz preset pickers and into the shared `visualization-toolbar`. Students see the same control in the same place whether they're on GCD, Extended Euclidean, or (eventually) Dijkstra, Knapsack, KMP. Shape of the new model (see spec at docs/superpowers/specs/2026-04-23-unified-task-picker-architecture.md): - `Task<TValues>` is a bundle of (default inputs, input schema, code snippet id, optional view-variant preference). Multiple tasks may share a code snippet when they're the same algorithm on different inputs; tasks with genuinely different code point at distinct snippets. No "scenario 3" — user-provided custom values only tweak the active task's inputs, never replace its code. - `LabPopover` is a new shared primitive using the existing `floating-panel` mixin, giving the customize-values popover the same chrome as the filter drop-downs on the algorithms page. Outside-click + Escape live here once, reusable across future overlay surfaces. - `LabNumberInput` is the matching BaseCVA control. Label sits as an eyebrow inside the chromed field, same structure as `LabSelect.__copy`, so stacking a select and a number input next to each other doesn't feel mixed-family. Migrated Euclidean GCD and Extended Euclidean to the new model. The legacy per-viz preset chip row in `scratchpad-lab-visualization`'s header is hidden for migrated algorithms; un-migrated viz families keep their old path until Phase C rolls through them. Code tab in the side panel now shows a small "Kod dla zadania: X" eyebrow above the snippet. Panel flex direction fixed to column (was defaulting to row and pushing the eyebrow into a sibling column). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Generalises the task path in algorithm-detail — `configHasTasks` type guard + shared `rebuildFromTask` helper work across any config kind, so future family migrations only add tasks to the config and set the scenario factory's `customValues` parameter; no more per-family branches in the dispatcher. Migrations: - Sieve of Eratosthenes: `upper` is customizable via the ✎ popover, size select collapsed (preset owns the scale now). Three tasks matching the old chip row. - Pointer-lab (two-pointers, sliding-window, palindrome, reverse, kadane): task picker wires up for all five. Custom input available for `target` (two-pointers) and `windowSize` (sliding-window); palindrome / reverse / kadane keep an empty schema so the ✎ button hides until the popover v2 supports strings and arrays. All per-family preset chip rows suppress automatically when tasks are active (the existing `pointerLabPresetOptions` / `sieveGridPresetOptions` computeds return `[]` under that condition). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Four traversal presets move to tasks, sharing one code snippet. Tree depth is tree-structural — no customizable scalar values — so the schema stays empty and the ✎ button hides, consistent with other families where custom-input in v1 doesn't apply. Size select remains so students can still flip between 7 / 15 / 31 nodes independently of the task. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Euclidean GCD and Extended Euclidean each ship 8 per-file task definitions with varied exam-style prompts: compute gcd, prove coprime, reduce fraction, count iterations, derive lcm, find modular inverse, solve Diophantine, prove Bézout. Scratchpad renders a "Zadanie:" / "Task:" block above the derivation (Newsreader italic, cyan accent) so the student reads a textbook prompt rather than a debug label. NotebookTask extends Task with summary / instruction / hints / difficulty and relaxes codeSnippetId to string | null — the Code tab renders an editorial "snippet in progress" placeholder when null, so new tasks can ship without a code walkthrough. taskPrompt is wired through scenario → generator → ScratchpadLabTraceState. utils/ flattened from 24 loose dirs into two buckets: - utils/helpers/ — 7 pure helpers (derive-sort-trace, dijkstra-graph, dsu-graph-layout, radix-visualization, tree-layout, visualization-motion, visualization-palette). - utils/scenarios/<family>/ — 14 families, with number-lab/ containing per-algorithm subdirs for euclidean-gcd/ and extended-euclidean/ (per-file task rosters). gcd-task.ts renamed to euclidean-gcd-task.ts for naming symmetry with extended-euclidean-task.ts. ~150 import paths updated across the codebase; type and export names unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three number-theory algorithms migrate from catalog stubs to live scratchpad-lab implementations, each with a typed scenario, per-file task roster (3 tasks per algorithm), generator with chalkboard narration, and spec tests. - **Miller-Rabin primality**: decompose `n - 1 = 2^r · d`, then run the square-chain witness check. Tasks: small-prime (29), composite- witness (25 with witness 2), Carmichael (561 with witnesses 2, 3). - **Chinese Remainder Theorem**: per-term `M_i · y_i · r_i` construction, sum, reduce. Tasks: two-congruences (mod 35), classic three-modulus (mod 105), smallest-positive (9·11·13 system). - **Pollard's rho**: Floyd tortoise-hare iteration table. Tasks: quick-factor 91, classic 8051 (83·97), cycle-failure on prime 53. All new tasks use `codeSnippetId: null` so the Code tab renders the "snippet in progress" placeholder. The config-builder spec is relaxed: an algorithm is allowed an empty `codeLines` array iff all its tasks opt out of code, keeping the rest of the invariant intact. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three wired fixes to the customize-values popover:
- **Form changes now actually propagate.** The popover's computed
pipeline didn't depend on FormGroup value changes, so `parsedValues`
cached the initial values and Apply emitted the untouched seed. A
`formValueTick` signal bumped on every `valueChanges` emission
reactivates the dependency graph on every keystroke.
- **String fields are supported.** `kind: 'string'` now renders a
proper control instead of blocking Apply with "field type not yet
supported" — unblocks Miller-Rabin witnesses and CRT congruence
systems. `kind: 'float'` arrives as a bonus.
- **Shared LabTextInput** extracted to `src/app/shared/controls/`
alongside `LabNumberInput` / `LabSelect` / `LabSlider`. Reuses the
`control-chrome` mixins so free-text inputs sit visually flush with
the rest of the lab-control family; `mono` flag keeps CSV values
(witnesses, CRT residue:modulus pairs) column-aligned.
Separately, task prompts in the scratchpad's "Zadanie:" / "Task:"
block now reflect popup values. `notebookInstructionText(task,
effectiveValues)` on `NotebookTask` wraps the instruction marker as
an `i18nText(key, params)`; every scenario factory (GCD, Extended
Euclidean, Miller-Rabin, CRT, Pollard's rho) feeds the current
effective values in. All 24 task instructions in PL + EN rewritten
with `{{n}}`, `{{a}}`, `{{b}}`, `{{witnesses}}`, `{{congruences}}`,
`{{M}}`, `{{c}}`, `{{x0}}` placeholders so the exam-style prompt
stays in sync with what the algorithm actually runs.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New notebook algorithm wired end-to-end: scenario parser for the
augmented-matrix string (`"1 1 | 5; 1 -1 | 1"`), Gauss-Jordan
generator that emits one KaTeX matrix snapshot per row operation
(swap / scale / eliminate), graceful singular-matrix fallback, and
a single canonical task `basic-2x2` whose integer arithmetic stays
clean through the entire sweep: `x + y = 5, x − y = 1 → (3, 2)`.
The scratchpad renders each snapshot as a `\left[\begin{array}
{cc|c}...\end{array}\right]` block, so the student sees the
structural transformation atomically rather than reading equations.
Users can edit the system in the customize-values popover (any size,
any coefficients); the "Zadanie:" prompt reformats live.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New notebook LP solver wired end-to-end. Scenario parses objective coefficients and ≤-constraint rows (same `"coeffs | rhs; ..."` shape as Gaussian so students reuse one matrix-entry convention). Generator builds the initial tableau with slack variables, emits a KaTeX augmented-matrix snapshot per pivot plus separate notes explaining entering-variable picks (most-negative reduced cost) and leaving- variable picks (min-ratio test). Graceful fallback branches cover unbounded LPs and an iteration cap. Canonical textbook task `basic-max-profit`: maximise `40x + 30y` subject to `x + y ≤ 12, 2x + y ≤ 16` — optimum at `(4, 8, z = 400)` in exactly two pivots, every tableau entry stays in integer-friendly fractions so the entire sweep reads cleanly. Users can edit objective and constraints in the customize-values popover (any number of variables / rows); the "Zadanie:" prompt re-renders live from the parsed values. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New streaming / randomized algorithm rendered in the scratchpad as an iteration table. Fill phase drops the first k items straight into the reservoir, sample phase rolls a deterministic LCG per later item and shows the k/(i+1) probability, the j draw, and the accept-or-skip decision. Reservoir state is redrawn after every step so the student watches the sample evolve. Canonical task `uniform-sample`: eight-integer stream, reservoir of size 3, seed 42 — five sample-phase iterations on top of the fill phase, reproducible between runs. Users can edit stream, k, and seed in the popover; the "Zadanie:" prompt re-renders live from the parsed values. `'reservoir-sampling'` added to the `ScratchpadLabMode` registry so the mode string checks out in the trace. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Final misc stub lands: iterative Cooley-Tukey FFT with bit-reversal permutation and `log₂ N` butterfly stages. Every butterfly emits its own scratchpad line showing `u`, the twiddle-scaled `t`, and the resulting `(u + t, u - t)` pair. Complex arithmetic is handled with a tiny local `Complex` type; twiddle factors show literal roots of unity for the canonical small-N runs (`1, -i, -1, i` for m = 4). Canonical task `basic-4-point`: real input `[1, 2, 3, 4]` → `[10, -2 + 2i, -2, -2 - 2i]`. Two stages, four butterflies, every intermediate value is integer-coordinate Gaussian — hand-verifiable. Non-power-of-two input lengths are rejected with a dedicated failure line so the radix-2 invariant stays clean. `'fft-ntt'` added to `ScratchpadLabMode`. With this all 21 misc / "Other" catalog entries are now fully implemented: 14 shipped earlier, 7 stubs landed this branch (Miller-Rabin, CRT, Pollard's rho, Gaussian elimination, Simplex, reservoir sampling, FFT). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR expands the algorithms feature set with new “lab” visualizations/trace panels and additional step-generator helpers, while also reorganizing scenario/helper import paths and adding test coverage for several math-centric algorithms.
Changes:
- Added Call Stack Lab / Call Tree Lab visualization and trace panel UIs.
- Added new algorithm generators (e.g., two-pointers, sliding-window, palindrome check, reverse string array, factorial) plus reusable
create*Stephelpers for new trace channels. - Refactored scenario/helper imports to a new
utils/scenarios/**(andutils/helpers/**) layout and introduced multiple new Vitest specs.
Reviewed changes
Copilot reviewed 151 out of 392 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| src/app/features/algorithms/components/call-tree-lab-visualization/call-tree-lab-visualization.html | New call-tree lab visualization template (tree + sidecar + stats + result). |
| src/app/features/algorithms/components/call-tree-lab-trace-panel/call-tree-lab-trace-panel.ts | New call-tree trace panel component (signals/computed for active node). |
| src/app/features/algorithms/components/call-tree-lab-trace-panel/call-tree-lab-trace-panel.scss | Styles for call-tree trace panel layout/chips/path. |
| src/app/features/algorithms/components/call-tree-lab-trace-panel/call-tree-lab-trace-panel.html | New call-tree trace panel template (facts, active node, stats, path). |
| src/app/features/algorithms/components/call-stack-lab-visualization/call-stack-lab-visualization.ts | New call-stack lab visualization component (state + header tone + preset wiring). |
| src/app/features/algorithms/components/call-stack-lab-visualization/call-stack-lab-visualization.html | New call-stack lab visualization template (frames + return rail + result). |
| src/app/features/algorithms/components/call-stack-lab-trace-panel/call-stack-lab-trace-panel.ts | New call-stack trace panel component (active frame + stringify helper). |
| src/app/features/algorithms/components/call-stack-lab-trace-panel/call-stack-lab-trace-panel.scss | Styles for call-stack trace panel (locals, chips, history). |
| src/app/features/algorithms/components/call-stack-lab-trace-panel/call-stack-lab-trace-panel.html | Call-stack trace panel template (facts, active frame, stats, returns). |
| src/app/features/algorithms/components/block-swap-visualization/block-swap-visualization.ts | Updated visualization-motion import path. |
| src/app/features/algorithms/components/bar-chart-visualization/bar-chart-visualization.ts | Updated visualization-motion import path. |
| src/app/features/algorithms/algorithms/z-algorithm/z-algorithm.ts | Updated scenario import path. |
| src/app/features/algorithms/algorithms/z-algorithm/z-algorithm.spec.ts | Updated scenario type import path. |
| src/app/features/algorithms/algorithms/wildcard-matching/wildcard-matching.ts | Updated DP scenario import path. |
| src/app/features/algorithms/algorithms/wildcard-matching/wildcard-matching.spec.ts | Updated DP scenario type import path. |
| src/app/features/algorithms/algorithms/union-find.ts | Updated DSU scenario import path. |
| src/app/features/algorithms/algorithms/union-find.spec.ts | Updated DSU scenario type import path. |
| src/app/features/algorithms/algorithms/two-pointers/two-pointers.ts | New pointer-lab two-pointers generator implementation. |
| src/app/features/algorithms/algorithms/tree-traversals/tree-traversals.ts | Updated scenario + tree-layout helper import paths. |
| src/app/features/algorithms/algorithms/traveling-salesman-dp.ts | Updated DP scenario import path. |
| src/app/features/algorithms/algorithms/traveling-salesman-dp.spec.ts | Updated DP scenario type import path. |
| src/app/features/algorithms/algorithms/suffix-array-lcp-kasai/suffix-array-lcp-kasai.ts | Updated string scenario import path. |
| src/app/features/algorithms/algorithms/suffix-array-lcp-kasai/suffix-array-lcp-kasai.spec.ts | Updated string scenario type import path. |
| src/app/features/algorithms/algorithms/suffix-array-construction/suffix-array-construction.ts | Updated string scenario import path. |
| src/app/features/algorithms/algorithms/suffix-array-construction/suffix-array-construction.spec.ts | Updated string scenario type import path. |
| src/app/features/algorithms/algorithms/subset-sum/subset-sum.ts | Updated DP scenario import path. |
| src/app/features/algorithms/algorithms/subset-sum/subset-sum.spec.ts | Updated DP scenario type import path. |
| src/app/features/algorithms/algorithms/sos-dp.ts | Updated DP scenario import path. |
| src/app/features/algorithms/algorithms/sos-dp.spec.ts | Updated DP scenario type import path. |
| src/app/features/algorithms/algorithms/sliding-window/sliding-window.ts | New pointer-lab sliding-window generator implementation. |
| src/app/features/algorithms/algorithms/simplex-algorithm/simplex-algorithm.spec.ts | Added simplex algorithm scenario-driven tests. |
| src/app/features/algorithms/algorithms/sieve-grid-step.ts | Added SortStep factory for sieve-grid trace channel. |
| src/app/features/algorithms/algorithms/scratchpad-lab-step.ts | Added SortStep factory + helper to attach scratchpad state (withScratchpad). |
| src/app/features/algorithms/algorithms/run-length-encoding/run-length-encoding.ts | Updated string scenario import path. |
| src/app/features/algorithms/algorithms/run-length-encoding/run-length-encoding.spec.ts | Updated string scenario type import path. |
| src/app/features/algorithms/algorithms/reverse-string-array/reverse-string-array.ts | New pointer-lab reverse-string-array generator implementation. |
| src/app/features/algorithms/algorithms/reservoir-sampling/reservoir-sampling.spec.ts | Added reservoir sampling scenario-driven tests. |
| src/app/features/algorithms/algorithms/regex-matching-dp/regex-matching-dp.ts | Updated DP scenario import path. |
| src/app/features/algorithms/algorithms/regex-matching-dp/regex-matching-dp.spec.ts | Updated DP scenario type import path. |
| src/app/features/algorithms/algorithms/rabin-karp/rabin-karp.ts | Updated string scenario import path. |
| src/app/features/algorithms/algorithms/rabin-karp/rabin-karp.spec.ts | Updated string scenario type import path. |
| src/app/features/algorithms/algorithms/profile-dp.ts | Updated DP scenario import path. |
| src/app/features/algorithms/algorithms/profile-dp.spec.ts | Updated DP scenario type import path. |
| src/app/features/algorithms/algorithms/pollards-rho/pollards-rho.spec.ts | Added pollard’s rho scenario-driven tests. |
| src/app/features/algorithms/algorithms/pointer-lab-step.ts | Added SortStep factory for pointer-lab trace channel. |
| src/app/features/algorithms/algorithms/palindromic-tree/palindromic-tree.ts | Updated string scenario import path. |
| src/app/features/algorithms/algorithms/palindromic-tree/palindromic-tree.spec.ts | Updated string scenario type import path. |
| src/app/features/algorithms/algorithms/palindrome-check/palindrome-check.ts | New pointer-lab palindrome check generator implementation. |
| src/app/features/algorithms/algorithms/number-lab-step.ts | Added SortStep factory for number-lab trace channel. |
| src/app/features/algorithms/algorithms/network-step.ts | Updated network scenario import path. |
| src/app/features/algorithms/algorithms/min-cost-max-flow.ts | Updated network scenario import path. |
| src/app/features/algorithms/algorithms/miller-rabin/miller-rabin.spec.ts | Added miller-rabin scenario-driven tests. |
| src/app/features/algorithms/algorithms/matrix-chain-multiplication/matrix-chain-multiplication.ts | Updated DP scenario import path. |
| src/app/features/algorithms/algorithms/matrix-chain-multiplication/matrix-chain-multiplication.spec.ts | Updated DP scenario type import path. |
| src/app/features/algorithms/algorithms/manacher/manacher.ts | Updated string scenario import path. |
| src/app/features/algorithms/algorithms/manacher/manacher.spec.ts | Updated string scenario type import path. |
| src/app/features/algorithms/algorithms/longest-palindromic-subsequence/longest-palindromic-subsequence.ts | Updated DP scenario import path. |
| src/app/features/algorithms/algorithms/longest-palindromic-subsequence/longest-palindromic-subsequence.spec.ts | Updated DP scenario type import path. |
| src/app/features/algorithms/algorithms/longest-increasing-subsequence/longest-increasing-subsequence.ts | Updated DP scenario import path. |
| src/app/features/algorithms/algorithms/longest-increasing-subsequence/longest-increasing-subsequence.spec.ts | Updated DP scenario type import path. |
| src/app/features/algorithms/algorithms/longest-common-subsequence/longest-common-subsequence.ts | Updated DP scenario import path. |
| src/app/features/algorithms/algorithms/longest-common-subsequence/longest-common-subsequence.spec.ts | Updated DP scenario type import path. |
| src/app/features/algorithms/algorithms/kruskals-mst.ts | Updated DSU scenario import path. |
| src/app/features/algorithms/algorithms/kruskals-mst.spec.ts | Updated DSU scenario type import path. |
| src/app/features/algorithms/algorithms/knuth-dp-optimization.ts | Updated DP scenario import path. |
| src/app/features/algorithms/algorithms/knuth-dp-optimization.spec.ts | Updated DP scenario type import path. |
| src/app/features/algorithms/algorithms/knapsack-01/knapsack-01.ts | Updated DP scenario import path. |
| src/app/features/algorithms/algorithms/knapsack-01/knapsack-01.spec.ts | Updated DP scenario type import path. |
| src/app/features/algorithms/algorithms/kmp-pattern-matching/kmp-pattern-matching.ts | Updated string scenario import path. |
| src/app/features/algorithms/algorithms/kmp-pattern-matching/kmp-pattern-matching.spec.ts | Updated string scenario type import path. |
| src/app/features/algorithms/algorithms/hungarian-algorithm.ts | Updated matrix scenario import path. |
| src/app/features/algorithms/algorithms/huffman-coding/huffman-coding.ts | Updated string scenario import path. |
| src/app/features/algorithms/algorithms/huffman-coding/huffman-coding.spec.ts | Updated string scenario type import path. |
| src/app/features/algorithms/algorithms/hopcroft-karp.ts | Updated network scenario import path. |
| src/app/features/algorithms/algorithms/gaussian-elimination/gaussian-elimination.spec.ts | Added gaussian elimination scenario-driven tests. |
| src/app/features/algorithms/algorithms/floyd-warshall/floyd-warshall.ts | Updated matrix scenario import path. |
| src/app/features/algorithms/algorithms/floyd-warshall/floyd-warshall.spec.ts | Updated matrix scenario type import path. |
| src/app/features/algorithms/algorithms/flood-fill/flood-fill.ts | Updated grid scenario import path. |
| src/app/features/algorithms/algorithms/flood-fill/flood-fill.spec.ts | Updated grid scenario type import path. |
| src/app/features/algorithms/algorithms/fibonacci-dp/fibonacci-dp.ts | Updated DP scenario import path. |
| src/app/features/algorithms/algorithms/fibonacci-dp/fibonacci-dp.spec.ts | Updated DP scenario type import path. |
| src/app/features/algorithms/algorithms/fft-ntt/fft-ntt.spec.ts | Added FFT/NTT scenario-driven tests. |
| src/app/features/algorithms/algorithms/factorial/factorial.ts | New number-lab factorial generator implementation. |
| src/app/features/algorithms/algorithms/extended-euclidean/extended-euclidean.spec.ts | Added extended Euclidean scenario-driven tests. |
| src/app/features/algorithms/algorithms/euclidean-gcd/euclidean-gcd.spec.ts | Added Euclidean GCD scenario-driven tests. |
| src/app/features/algorithms/algorithms/edmonds-karp.ts | Updated network scenario import path. |
| src/app/features/algorithms/algorithms/edit-distance/edit-distance.ts | Updated DP scenario import path. |
| src/app/features/algorithms/algorithms/edit-distance/edit-distance.spec.ts | Updated DP scenario type import path. |
| src/app/features/algorithms/algorithms/dp-with-bitmask.ts | Updated DP scenario import path. |
| src/app/features/algorithms/algorithms/dp-with-bitmask.spec.ts | Updated DP scenario type import path. |
| src/app/features/algorithms/algorithms/dp-on-trees.ts | Updated DP scenario import path. |
| src/app/features/algorithms/algorithms/dp-on-trees.spec.ts | Updated DP scenario type import path. |
| src/app/features/algorithms/algorithms/dp-convex-hull-trick.ts | Updated DP scenario import path. |
| src/app/features/algorithms/algorithms/dp-convex-hull-trick.spec.ts | Updated DP scenario type import path. |
| src/app/features/algorithms/algorithms/divide-conquer-dp-optimization.ts | Updated DP scenario import path. |
| src/app/features/algorithms/algorithms/divide-conquer-dp-optimization.spec.ts | Updated DP scenario type import path. |
| src/app/features/algorithms/algorithms/dinic-max-flow.ts | Updated network scenario import path. |
| src/app/features/algorithms/algorithms/crt/crt.spec.ts | Added CRT scenario-driven tests. |
| src/app/features/algorithms/algorithms/coin-change/coin-change.ts | Updated DP scenario import path. |
| src/app/features/algorithms/algorithms/coin-change/coin-change.spec.ts | Updated DP scenario type import path. |
| src/app/features/algorithms/algorithms/climbing-stairs/climbing-stairs.ts | Updated DP scenario import path. |
| src/app/features/algorithms/algorithms/climbing-stairs/climbing-stairs.spec.ts | Updated DP scenario type import path. |
| src/app/features/algorithms/algorithms/call-tree-lab-step.ts | Added SortStep factory for call-tree-lab trace channel. |
| src/app/features/algorithms/algorithms/call-stack-lab-step.ts | Added SortStep factory for call-stack-lab trace channel. |
| src/app/features/algorithms/algorithms/burst-balloons/burst-balloons.ts | Updated DP scenario import path. |
| src/app/features/algorithms/algorithms/burst-balloons/burst-balloons.spec.ts | Updated DP scenario type import path. |
| src/app/features/algorithms/algorithms/burrows-wheeler-transform/burrows-wheeler-transform.ts | Updated string scenario import path. |
| src/app/features/algorithms/algorithms/burrows-wheeler-transform/burrows-wheeler-transform.spec.ts | Updated string scenario type import path. |
| src/app/features/algorithms/algorithms/aho-corasick/aho-corasick.ts | Updated string scenario import path. |
| src/app/features/algorithms/algorithms/aho-corasick/aho-corasick.spec.ts | Updated string scenario type import path. |
| src/app/features/algorithms/algorithms/a-star-pathfinding/a-star-pathfinding.ts | Updated grid scenario import path. |
| src/app/features/algorithms/algorithms/a-star-pathfinding/a-star-pathfinding.spec.ts | Updated grid scenario type import path(s). |
| src/app/features/algorithms/algorithm-detail/algorithm-detail.html | Wired tasks/custom values + new trace channels into algorithm detail view. |
| src/app/features/algorithms/algorithm-detail/algorithm-detail-config/algorithm-detail-config.spec.ts | Updated config expectations for algorithms without code snippets. |
| src/app/features/algorithms/algorithm-card/algorithm-card.ts | Enabled MathText usage in algorithm cards. |
| src/app/features/algorithms/algorithm-card/algorithm-card.scss | Styled MathText within card description and metrics. |
| src/app/features/algorithms/algorithm-card/algorithm-card.html | Rendered description/metrics via MathText for consistent math formatting. |
| src/app/core/i18n/i18n-keys.ts | Added new i18n keys for tasks, snippet-missing state, multiple trace panels, viz options. |
| package.json | Added KaTeX dependency. |
| .claude/skills/ohno-viz-polish-checklist/SKILL.md | Added internal visualization polish checklist documentation. |
| .claude/skills/ohno-visualization-anatomy/SKILL.md | Added internal “visualization anatomy” documentation. |
| .claude/skills/ohno-ux-principles/SKILL.md | Added internal UX principles documentation. |
| .claude/skills/ohno-scratchpad-narrative/SKILL.md | Added internal scratchpad narrative guidelines. |
| .claude/skills/ohno-motion-and-a11y/SKILL.md | Added internal motion & accessibility guidelines. |
| .claude/skills/ohno-i18n-discipline/SKILL.md | Added internal i18n discipline guidelines. |
| .claude/skills/ohno-design-tokens/SKILL.md | Added internal design tokens reference. |
| .claude/skills/ohno-algorithm-step-generator/SKILL.md | Added internal algorithm step-generator guidelines. |
| .claude/agents/ohno-design-reviewer.md | Added internal design reviewer agent spec. |
Comments suppressed due to low confidence (1)
src/app/features/algorithms/algorithms/palindrome-check/palindrome-check.ts:1
- For an empty input string,
rightbecomes-1, and subsequent pointer/state construction will emit pointers with an invalid index. Handlechars.length === 0as a special case (empty string is a palindrome) and yield a completed step without invalid pointer indices.
import { marker as t } from '@jsverse/transloco-keys-manager/marker';
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…expression' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
…expression' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
…ort, function or class' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
…ort, function or class' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
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.
No description provided.