Skip to content

Feat/other algorithms#26

Merged
SparrowVic merged 46 commits into
mainfrom
feat/other-algorithms
Apr 24, 2026
Merged

Feat/other algorithms#26
SparrowVic merged 46 commits into
mainfrom
feat/other-algorithms

Conversation

@SparrowVic
Copy link
Copy Markdown
Owner

No description provided.

SparrowVic and others added 30 commits April 23, 2026 00:21
…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>
Copilot AI review requested due to automatic review settings April 24, 2026 16:53
Comment thread src/app/shared/components/math-text/math-text.utils.ts Dismissed
Comment thread src/app/features/algorithms/algorithms/dinic-max-flow.ts Dismissed
Comment thread src/app/features/algorithms/algorithms/hopcroft-karp.ts Dismissed
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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*Step helpers for new trace channels.
  • Refactored scenario/helper imports to a new utils/scenarios/** (and utils/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, right becomes -1, and subsequent pointer/state construction will emit pointers with an invalid index. Handle chars.length === 0 as 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.

Comment thread src/app/features/algorithms/algorithms/two-pointers/two-pointers.ts
Comment thread src/app/features/algorithms/algorithms/two-pointers/two-pointers.ts
Comment thread src/app/features/algorithms/algorithms/crt/crt.spec.ts
SparrowVic and others added 4 commits April 24, 2026 19:11
…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>
@SparrowVic SparrowVic merged commit 4f76c94 into main Apr 24, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants