Charlie KrugThe Build Log

← All posts

Binary search feels different when the numbers disappear

Bisect removes higher-or-lower hints from the guessing game. Each cut dims the impossible half, turning binary search into something you can see and feel.

Make one guess and the bright bar splits. One side goes dark, the other stays alive, and no message tells you whether you were high or low. The only way forward is to read what happened to the space.

Bisect is a small binary-search game with zero text hints during play. I built it because ordinary number-guessing games hide the interesting part behind two words. You read “higher” or “lower,” update a number in your head, and watch the algorithm scroll past as dialogue. The shrinking search space never becomes tangible.

Here, the bar is both the board and the explanation. It works without language, but the more important constraint is that there is no separate tutorial layer doing the thinking for you.

The hint is geometry

Binary search works by discarding candidates, not by guessing magically well. Start with 100 possible values and choose near the middle. The answer to that guess lets you eliminate roughly 50 values at once. Repeat and the surviving set falls to about 25, then 13, then 7. In the ideal case, the worst-case guess count grows as ceil(log2 N), so doubling the range costs only one more guess.

Bisect draws that candidate set as one horizontal bar. A guess places a cut through it. The side that cannot contain the target dims and becomes unavailable; the surviving side carries the color into the next turn. The win screen compares the guesses you took with that logarithmic target, but it withholds digits while you are playing. You have to judge the midpoint by eye.

I used HTML Canvas for the bar instead of a row of DOM elements. That gives the cut, dimming, and redraw one continuous coordinate system, including sub-pixel positions when the remaining interval gets narrow. The tween is functional feedback: if the losing half simply vanished, you would see the new state but miss the operation that produced it. A short synthesized sound marks the same transition, with no audio files and a persisted mute switch.

The levels break useful assumptions

Making the range larger would only ask you to repeat the same move. The three levels instead change the structure of the data.

The first range is sorted normally, so position and value rise together. The second is rotated: imagine 70, 71, ... 100, 1, 2, ... 69 laid across the same bar. Now “the left side is lower” is false around the wrap point. This is the rotated-sorted-array version of binary search, where you first identify which half is ordered, then ask whether the target could be inside it.

The third range contains duplicates. Equal values can make both halves look plausible, so a guess does not always justify throwing away half the bar. The question changes from “which side looks smaller?” to “which side is guaranteed not to contain the target?” If play narrows to a run of identical values, typing the value cannot distinguish positions; tapping the bar breaks the tie. That input detail falls directly out of the algorithmic edge case.

This is still a deliberately compact game, not a full binary-search course. With no explanatory text, the first cut can be cryptic for a few seconds, and the game never names the rule you just discovered. I think that pause is useful, but it is a real cost of making the visualization carry the whole lesson. The implementation stays equally narrow: TypeScript, Canvas, a hand-rolled game loop, and no backend.

Try it

Open Bisect, make your first guess near the center, and watch which color survives. Try to finish the 1-to-100 range in seven guesses, then use the same instinct on the rotated level and see where it fails. You can type a value or tap the bar, and the source is on GitHub.

Bisect is live. Free, in your browser, no signup.

This post is part of the build log: every app my automated factory ships gets written up here, honestly. Browse everything at apps.charliekrug.com. Comments are open below.

Comments

Loading comments…