Search Algorithm Visualizations in the terminal, with a chat-style UI.
Search-CLI is a companion to Sort-CLI: the same
single-binary C99 program drawn with VT escape codes and Sort-CLI's color gradients,
but interactive. It looks and works like Claude's CLI: a welcome box, a transcript of
⏺ replies with ⎿ details, a bordered prompt with slash-command autocomplete,
a spinner while an animation plays, and a hint line under the prompt.
Type a slash command, or just ask: binary 42, astar on a maze, compare all,
explain jump.
| Array search | Best | Average | Worst | Needs sorted data |
|---|---|---|---|---|
linear |
O(1) | O(n) | O(n) | no |
binary |
O(1) | O(log n) | O(log n) | yes |
leftmost |
O(log n) | O(log n) | O(log n) | yes (first copy of duplicates) |
jump |
O(1) | O(√n) | O(√n) | yes |
interpolation |
O(1) | O(log log n) | O(n) | yes |
exponential |
O(1) | O(log i) | O(log n) | yes |
fibonacci |
O(1) | O(log n) | O(log n) | yes |
ternary |
O(1) | O(log₃ n) | O(log₃ n) | yes |
| Path search (grid) | Path it finds |
|---|---|
bfs |
fewest moves |
dfs |
any path |
dijkstra |
cheapest |
astar |
cheapest, with fewer cells expanded |
greedy |
any path, very few cells expanded |
Array searches draw the values as bars: the range that can still hold the target is
in color with a ╰──╯ bracket under it, eliminated values turn grey, probed values
are yellow with ▲, and a hit turns green. Every step is narrated
(mid = (12 + 23) / 2 = 17, a[17] = 62) with live probe and comparison counts.
Path searches run on a grid from S to G. Visited cells are colored by the order
they were expanded, the frontier shows as ○, mud (≈≈) costs 5 to cross, and the
final path is drawn in white, so it stands out from every gradient. The cell being expanded is marked with an orange ◆.
Bars and visited cells are colored by a gradient. /gradient lists the presets with
a swatch of each:
rainbow and pastel (from Sort-CLI), viridis, plasma, inferno, magma and
cividis (matplotlib), turbo, ocean, fire, sunset, forest, ice, candy,
cool, claude and grayscale.
/gradient magma switch preset (typing just "magma" works too)
/gradient viridis reverse a preset, flipped
/gradient reverse flip the current gradient
/gradient #1e3a8a #f59e0b #fef3c7 your own stops: 2-18 colors, #rrggbb, #rgb or xterm 0-255
Gradients are blended in 24-bit color when the terminal says it supports it
(COLORTERM=truecolor), and mapped to the nearest of the 256 xterm colors otherwise.
/color truecolor and /color 256 switch by hand; --gradient <preset>,
--truecolor and --256 do the same from the command line. /theme still works as
another name for /gradient.
Hoot is a pink pixel owl (14×12 pixels drawn with half blocks) that sits above the
prompt. While a search plays its eyes sweep left and right; it cheers a hit
("found it!", "a path!"), frowns at a miss or an error, blinks now and then, and
falls asleep after a minute without keys. /pet off hides it; it also steps aside
when the window is smaller than 60×22 or when requests are piped in.
| Command | What it does |
|---|---|
/run [algo] [target] |
Run a search and watch it (random target if none) |
/step [algo] [target] |
Same, starting paused: walk through it with ←/→ |
/find <target> |
Search with the current algorithm |
/compare [target|all|path] |
Run every algorithm on the same input and chart the cost |
/explain [algo] |
Summary, complexity and pseudocode |
/algos |
List every algorithm |
/use <algo> |
Pick the current array or path algorithm |
/data [kind] [n] |
Make an array: sorted, uniform, skewed, dups, random |
/data v1 v2 … |
Search your own values |
/sort |
Sort the current array |
/grid [kind] [WxH] |
Make a grid: maze, open, mud, empty |
/path [algo] |
Run a path search on the grid |
/gradient [preset|colors…] |
Pick a color gradient, reverse it, or make your own (see below) |
/color [truecolor|256] |
Smooth 24-bit gradients or the 256-color palette |
/speed [ms], /seed <n> |
Animation delay, reproducible data |
/pet [on|off] |
Show or hide Hoot |
/clear, /help, /exit |
Things worth trying: /data uniform then /compare (interpolation wins), then
/data skewed and /compare again (interpolation loses); /data dups with
/run leftmost; /grid mud then /compare path (BFS walks through mud, Dijkstra
and A* go around, A* expands far fewer cells).
/opens the command menu;↑/↓choose,Tabcompletes,Enterruns. Arguments (algorithms, data kinds, grids, gradients) complete the same way.↑/↓with no menu open walk through your history;?shows shortcuts.Ctrl-A/Ctrl-E/Ctrl-U/Ctrl-K/Ctrl-Wedit the line,Escclears it,Ctrl-Lredraws,Ctrl-Ctwice orCtrl-Dexits.- While an animation plays:
spacepause/resume,←/→step,Home/End,+/-speed,Enterjump to the result,Escstop.
make # or: mingw32-make on Windowsor compile directly:
cc -O2 -std=c99 search-cli.c -o search-cli -lmsearch-cli [OPTIONS]
OPTIONS:
-v, --version Display program version information
-h, --help Display this help message
-s, --speed <ms> Delay per animation step (default: 300, range 10-5000)
--seed <n> Make generated data and targets reproducible
-g, --gradient <name> Color gradient preset (rainbow, viridis, plasma, inferno, ...)
--truecolor Smooth 24-bit gradients (default when COLORTERM=truecolor)
--256 Use the 256-color palette
--no-color Plain output (also when NO_COLOR is set)
Requests can be piped in, one per line; the app then prints each result without animating:
printf '/data uniform\n/compare\n/explain interpolation\n' | ./search-cli --seed 1make testtest.c runs everything without the UI and checks that:
- every array search finds exactly the values that are present, on sorted, uniform, skewed, duplicate-heavy and (for linear search) unsorted data; leftmost binary search returns the first copy
- each trace is consistent: it opens with a start step, ends with found/missing, counters never go down and the live range never loses the target
- probe counts stay within known bounds (e.g. binary search ≤ ⌊log₂ n⌋ + 1)
- every path is valid, a path is found exactly when the goal is reachable, BFS finds the fewest moves and Dijkstra/A* the cheapest cost (checked against a brute-force relaxation)
- every frame fits the window at 50 to 200 columns, and every command and plain request answers without errors
The random inputs use a seed printed at the top of the report; pass it back to reproduce a run:
./search-cli-test 1234| File | Contents |
|---|---|
term.h |
raw keyboard input with timeouts, window size, output |
text.h |
string builder, colors, markup and word wrap |
gradient.h |
gradient presets, custom stops, 24-bit and 256-color output |
data.h |
the array and its generators |
search.h |
array searches, each recording a step trace |
grid.h |
grids, frontier (queue/stack/heap) and path searches |
render.h |
draws one step of an array or grid search |
pet.h |
Hoot: sprite, moods and the strip above the prompt |
ui.h |
transcript, live region, spinner and the player |
cmds.h |
commands, plain requests, autocomplete, line editor, main loop |
Algorithms never draw: they record a trace of steps, and the player renders any step on demand, which is what makes stepping backwards possible.
Tested on macOS (Apple Clang 21). Linux should work as is (-lm is in the makefile).
The Windows code path (console VT mode, _getch input) follows Sort-CLI but has not
been tested yet.
Requirements:
- macOS or Linux with a UTF-8, 256-color terminal
- Windows 10 Build 10586 or later (for VT/ANSI support)


