Skip to content

Repository files navigation

search-cli

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.

Algorithms

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 ◆.

Gradients

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

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.

Commands

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).

Controls

  • / opens the command menu; ↑/↓ choose, Tab completes, Enter runs. 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-W edit the line, Esc clears it, Ctrl-L redraws, Ctrl-C twice or Ctrl-D exits.
  • While an animation plays: space pause/resume, ←/→ step, Home/End, +/- speed, Enter jump to the result, Esc stop.

Building

make                # or: mingw32-make on Windows

or compile directly:

cc -O2 -std=c99 search-cli.c -o search-cli -lm

Usage

search-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 1

Testing

make test

test.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

Code layout

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.

Screenshots

Binary search, paused A* on a maze Gradient presets

Notes

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)

Releases

Packages

Contributors

Languages