Part 3's fast plan empties the bag on a furnished 12×12 room in 178 moves; the best plan takes 170, and this part proves it. A plan as a choice among trips, column generation with the dual prices of the fields, pricing …
Part 3's fast route cleans a furnished 20×20 room in 243 commands. The shortest route takes 221, and this part proves nothing shorter exists: parity and whole numbers put back into Part 8's linear program, branch and …
Part 3's fast route cleans a furnished 40×40 room in 1,327 commands, and Part 3 could only prove that no route needs fewer than 1,037. Written as a linear program, the same question proves 1,122. The simplex method from …
Put five squares round every corner of the robot's floor instead of four and the floor can't lie flat: it ruffles like a lettuce leaf. Within ten steps there are 16,737 fields instead of 221, the 50,000-command budget …
Send the cleaning robot up the walls of a pool or over the outside of a box, and three left turns can bring it home. Every corner is ninety degrees short, no compass fits the whole surface, the checkerboard fails at each …
Glue the room's ends with a half twist, like a Möbius strip, and every lap swaps the robot's up and down. Part 1's commands walk it into walls, the blind robot's dock needs an arrow, and union-find with parity tells, one …
Glue the room's left edge to its right and its top to its bottom, as in Asteroids. The cleaning robot's walk still works, but the blind robot from Part 3 never stops and the checkerboard bound gives wrong answers. A …
The fewest commands, a robot with no map, a dock that empties the bag and a second robot that must not collide. Each new rule turns the cleaning robot puzzle into a different classic problem: a travelling-salesman path, …
Every floor field gets some dirt and the robot a bag that fills up, then a battery that runs out. The cleaning robot puzzle turns into subset sum, a connected knapsack and the orienteering problem, with exact solvers …
One robot, rooms full of furniture and a 50,000-command budget: a short depth-first search cleans it all. The first part explains it line by line, traces it by hand, proves it correct and checks it on 3,000 random rooms.
A solver test failed in February and a hard-coded relaxation factor of 1.5 took the blame. Measured on every grid, 1.5 was within a sweep of the best on exactly one of them, February's failure had another cause, and the …
A profile blamed dispatch(), and all four proposed fixes made the virtual call inside it cheaper. Measured, that call is 10 ns of a 333 ns budget and finding the handler is 75. Then the instruction cache, a plugin ABI in …
Part 1 of this saga shipped a compare-and-swap loop that gave up after 100 tries. It can fail at most 64 times. What really loses an Add is Union, with no retry involved and nothing the race detector can see. With …
Five tests segfaulted on Linux and passed on Windows, on the same commit. The bug was a struct whose type quietly demanded an alignment malloc never promised — and the faulting instruction was not where the crash looked …
An atomic-first Go Bloom filter still tripped the race detector. A war story about the read that looked benign, and what the Go memory model has to say about it.
Rank and select turn two expensive log queries into constant-time lookups. What that costs, what it buys, and why the same code can honestly report both 2ns and 13ns.
A line-by-line reading of avx2.s: runtime AVX2 detection, and hand-written Go assembly for population count, bitwise OR and AND, and clearing 32 bytes at a time.
Making the Bloom filter thread-safe cost 8–12x in throughput. The culprit was a heap allocation on every Add and Contains; the fix was a stack array for small hash counts.
Concurrent reads were panicking in a Go Bloom filter because Contains() quietly mutated shared scratchpad state. How the race was found, fixed, and what the fix cost.
A benchmark that measured fmt.Sprintf instead of the filter, several pprof sessions, one optimisation that made things worse, and the data-structure change that finally paid.
Gall's Law, Lehman, Brooks, Wirth and the rest — each with the project that ignored it, the project that respected it, and a story from my own trenches.
What computational fluid dynamics actually is — the history from Euler to WENO schemes, why analytical solutions and wind tunnels both hit walls, and where the hard parts lie.
The Navier–Stokes equations from four playground ideas — mass, momentum, viscosity and pressure — through Euler, Navier and Stokes to the vector calculus that writes them down.
Bringing AVX2 to Project Euler 38 — what 256-bit registers buy when the same pandigital check runs over thousands of candidates, and how the C++ compares to scalar code.
Vectorising Project Euler 38 in MATLAB: build the concatenated products as a matrix, test every candidate in one pass, and let the language do what it is actually good at.
A C# solution that prunes by digit length instead of brute-forcing: the constraint that the products must total nine digits bounds k to a handful of ranges.
Turning the brute-force Python solution lean: integer concatenation instead of strings, a 10-bit mask for the pandigital test, and early exits that prune the search.
A step-by-step Python solution to Project Euler 38: why the search stops at 9999, how to build each concatenated product, and a straightforward pandigital check.
Project Euler 38 without a computer: digit-count arithmetic narrows the search to four-digit numbers starting with 9, and the rest is pen, paper and a little logic.
What makes 192384576 special, and why concatenating the multiples of 9327 gives the largest 1–9 pandigital number you can build this way. No code, just the puzzle.