A field guide to the technique: the idea, a real solved task end to end, and the raw material behind the paper.
Companion page to our arXiv paper. This page carries the detail that doesn't belong in a formal paper, full LLM conversations, real solved programs, and additional charts. Numbers here get updated as we run more of the task set, so treat this as a living page rather than a snapshot.
The core idea
ARC-AGI-2 tasks give you a handful of input→output grid examples and ask you to figure out the rule, then apply it to a new grid. We build solutions to these puzzles by combining two things that are each, on their own, not very good at this job.
A large language model, on its own, is fine but slow. It can reason about a task's transformation rule in plain language, and it often proposes something plausible on the first try. But every attempt costs a real LLM call, and the number of attempts you can afford is bounded by hardware, how many copies of the model you can run, not by any real ceiling on how many variations might be worth trying.
A genetic algorithm, on its own, basically doesn't work. We tried it: seed a population entirely at random over our 41-operation DSL and let it evolve, no LLM involved anywhere. With chromosomes capped at 20 operations, the raw search space is around 4120 operation sequences, and that's before you even count the five arguments each operation takes. Blind search over that space essentially never lands on an exact answer in a reasonable number of generations.
So we built a bridge between them.
Every so often the LLM's own proposal is already exact, no search needed at all. We don't have a tidy explanation for why that happens as often as it does.
The LLM doesn't write one guess. It's prompted to propose a broad, generous set of candidate programs: the leading hypothesis, plus every plausible variant of it. That set becomes the seed material for a genetic algorithm that runs entirely on the GPU as a single batched tensor operation, with zero further LLM calls, evolving the population toward an exact pixel match.
What actually counts as solved. A chromosome can match every training example perfectly and still get the test grid wrong, since training pairs are the only thing our search can see while it's running. So we check every claimed solve directly against the real test output before we count it. On our 60-task sample, the LLM's own proposals solve 2 tasks outright with no search at all, and the genetic algorithm adds 4 more through real evolution, 6 verified solves total. A further 3 candidates matched every training example but got the test grid wrong, and we don't count those, even though an earlier pass at this analysis did before we caught it. More on that below.
The Machine
The "Machine" is the shared language both the LLM and the genetic algorithm address directly. It has three parts:
Perception, turning a raw grid into registers and objects, is deterministic and greedy: color-channel splitting plus neighbor connectivity. It's a simple first pass, and we know it misses groupings a person would spot immediately. But it gives every chromosome, every prompt, and every mutation a shared vocabulary to point at, "the dominant color," "object 3's bounding box", instead of hard-coding values that would only make sense for one training pair.
A real task, start to finish
Here's an actual run, unedited except for length, on task 017c7c7b, a 6×3 input mapped to a 9×3 output. This one's a genuine, verified solve: we checked the winning chromosome against the real test grid ourselves, not just the training pairs.
The LLM's step is a fixed four-stage conversation. Below is that conversation, real and mostly unabridged (the full operation catalogue and a few argument lists are elided for length, marked with […] exactly where our source notes elided them).
None of these four chromosomes was an exact match on their own, the best scored 53% mean pixel accuracy against the training pairs. They became the seed pool for both GA populations, which reached an exact match by recombining and mutating around them. (Across different runs of this same task we've seen the exact match land anywhere from generation 22 to 25, ordinary run-to-run noise.) We then checked the winning chromosome against the real held-out test grid, and it's correct: this is one of the 6 verified solves in our 60-task sample.
What this one example shows: the LLM never had to be right, it had to be generous. Four different hypotheses, each wrong, gave the genetic algorithm enough raw material to find the exact answer in a few dozen generations. That division of labor is the whole idea.
The 41-operation language
A chromosome is a sequence of 20 genes; each gene is an opcode plus five arguments. 27 "core" operations are always available for mutation to draw on. 14 "gated" operations are narrower and more expensive, and only enter a task's search space if the LLM itself proposed one, since they're too specific for random mutation to stumble into usefully on its own, but cheap to unlock the moment the LLM's reasoning actually calls for one.
| Op | Tier | What it does |
|---|---|---|
| COPY | core | Copy one channel to another. |
| TRANSLATE | core | Shift content by (dr,dc) cells. |
| RAY_STEP | core | Smear content along (dr,dc) via an O(log n) doubling reach. |
| RECOLOR | core | Set every content cell of a channel to one color. |
| OVERLAY_K0 | core | Paste a channel's content onto OUT, leaving the rest alone. |
| FLIP_H / FLIP_V / ROT90 / ROT180 / ROT270 / TRANSPOSE | core | Standard grid symmetries. |
| CROP_BBOX | core | Trim a channel to its tight content bounding box. |
| TILE | core | Repeat a content block as a kr×kc grid of copies. |
| MAP_RANK | core | Recolor objects by size rank. |
| EXTEND | core | Shoot a ray from a channel to the grid edge. |
| FLOOD | gated | Fill enclosed background holes. |
| GRAVITY | gated | Every non-background cell slides until it hits something. |
| PICK | gated | Select the one object matching a property (biggest, touches border…). |
| PANEL_BOOL | gated | Split OUT at a detected divider, boolean-combine the two panels. |
| SCALE | gated | Blow up each cell into an fr×fc block. |
| COPY_PASTE | gated | Repeat a channel's own content periodically along a direction. |
| … 25 more | n/a | Full table of all 41 ops, with args, is in the paper's appendix. |
What we've found so far
Full results, tables, and confidence intervals live in the paper. Here we want to walk through the two findings that matter most, with the actual charts.
The biggest thing we learned wasn't about the LLM or the GA, it was about our own definition of "solved." Early on we counted a chromosome as solved once it exactly reproduced every training pair. That's a reasonable thing for the search itself to optimize for, it's the only signal available during a run, but it's not the same claim as "this chromosome is correct." We went back and checked every one of our 9 candidate solves against the real test grid by hand. 6 held up. 3 didn't: they fit the training examples perfectly and still got the actual answer wrong. We're leaving that in, not because it's flattering, but because it's exactly the kind of gap this whole approach needs to be honest about, and because it changes the headline number from 9 out of 60 to 6 out of 60. We'd rather report the smaller, correct number.
Best (solid) and mean (dashed) population fitness by generation, for three verified solves and three unsolved tasks. All three solved examples here were checked against the real test grid, not just the training pairs. Solved tasks tend to show a staircase pattern, long plateaus, then a sudden jump, though one of the three (0c9aba6e) climbs gradually instead, with the whole population improving together rather than one lucky mutation breaking through.
The clearest evidence we have that the LLM's contribution isn't redundant with the genetic algorithm's: the same three tasks, with LLM seeding (solved exactly and verified correct, every time) versus a matched control with zero LLM-derived material (never exact, even after 200 generations).
One honest miss, worth reporting because it's informative: an early hypothesis, from a small 3-task sample, suggested that how many candidate chromosomes the LLM proposes predicts how fast the genetic algorithm converges. Retested on the larger 60-task sample, using only the verified solves, it didn't hold up. We're leaving that in the paper as a negative result instead of quietly dropping it.
Open questions
- Why does an exact training fit sometimes just not generalize? Three of our nine candidate solves matched every training example perfectly and still got the test grid wrong. We don't yet have a good story for what separates those from the six that generalized.
- Why does the LLM ever produce an exact answer at all? It happens more than chance would suggest, on tasks it was never trained to solve, using a DSL it's only seen in-context. We still don't have an explanation.
- The no-LLM control needs to run at full scale. Right now it's three tasks, matched against ones we already solve with LLM help. The real test is running it across the full set, including tasks we currently can't solve at all, and with the same 41-op vocabulary in both conditions so we're isolating one variable at a time.
- What drives chromosome attrition? On some tasks over 90% of what the LLM proposes fails basic syntax verification before it ever reaches the genetic algorithm. We don't know yet why some tasks are so much worse than others.