<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Cellular Automata From First Principles on AIBussin — AI applications, systems and books</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/</link><description>Recent content in Cellular Automata From First Principles on AIBussin — AI applications, systems and books</description><generator>Hugo</generator><language>en-US</language><lastBuildDate>Mon, 10 Aug 2026 21:01:00 +0100</lastBuildDate><atom:link href="https://aibussin.com/books/cellular-automata-from-first-principles/index.xml" rel="self" type="application/rss+xml"/><item><title>How Can Tiny Rules Build Complex Worlds?</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/01-chapter/</link><pubDate>Mon, 10 Aug 2026 18:20:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/01-chapter/</guid><description>&lt;p&gt;A cellular automaton begins with almost nothing.&lt;/p&gt;&#10;&lt;p&gt;You need:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;a collection of cells,&lt;/li&gt;&#10;&lt;li&gt;a state for each cell,&lt;/li&gt;&#10;&lt;li&gt;a neighborhood,&lt;/li&gt;&#10;&lt;li&gt;and a rule that tells each cell what to become next.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;That is enough.&lt;/p&gt;&#10;&lt;p&gt;There is no central controller.&lt;/p&gt;&#10;&lt;p&gt;There is no object that knows what the final pattern should look like.&lt;/p&gt;&#10;&lt;p&gt;There is only local state changing through time.&lt;/p&gt;&#10;&lt;p&gt;And yet some local rules produce stripes, fronts, oscillators, moving structures, traffic waves, cave systems, self-repairing patterns, and systems rich enough to perform computation.&lt;/p&gt;</description></item><item><title>Build Your First Automaton</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/02-chapter/</link><pubDate>Mon, 10 Aug 2026 18:21:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/02-chapter/</guid><description>&lt;p&gt;In the previous chapter we reduced a cellular automaton to four things:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;space&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;state&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;neighborhood&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rule&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we are going to build one.&lt;/p&gt;&#10;&lt;p&gt;Not a framework.&lt;/p&gt;&#10;&lt;p&gt;Not a library.&lt;/p&gt;&#10;&lt;p&gt;One update step.&lt;/p&gt;&#10;&lt;p&gt;That is enough to expose the whole mechanism.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="start-with-a-one-dimensional-world"&gt;Start with a one-dimensional world&lt;/h2&gt;&#10;&lt;p&gt;Create a row of cells and turn on the center cell:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; numpy &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; np&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;width &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;41&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;state &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;zeros(width, dtype&lt;span style="color:#f92672"&gt;=&lt;/span&gt;np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;uint8)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;state[width &lt;span style="color:#f92672"&gt;//&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;print(state)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Conceptually:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;....................#....................&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We will use &lt;code&gt;0&lt;/code&gt; for an empty cell and &lt;code&gt;1&lt;/code&gt; for an active cell.&lt;/p&gt;</description></item><item><title>Encode All 256 Elementary Rules</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/03-chapter/</link><pubDate>Mon, 10 Aug 2026 18:22:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/03-chapter/</guid><description>&lt;p&gt;In the previous chapter we built one rule: a cell becomes active when exactly one of its three neighbors is active. That turned out to be Rule 22, but we treated it as a hand-written function.&lt;/p&gt;&#10;&lt;p&gt;Now we generalize. Instead of writing one function per rule, we encode every possible elementary rule as a single integer — and get all 256 automata for the price of one simulator.&lt;/p&gt;&#10;&lt;p&gt;An elementary cellular automaton has only three inputs per cell:&lt;/p&gt;</description></item><item><title>Rule 30 and the Surprise of Complexity</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/04-chapter/</link><pubDate>Mon, 10 Aug 2026 18:23:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/04-chapter/</guid><description>&lt;p&gt;The previous chapter gave us a simulator that can run any of the 256 elementary rules. Now we pick one and look at it closely. Rule 30 is the standard demonstration of why cellular automata are worth studying.&lt;/p&gt;&#10;&lt;p&gt;Its transition table contains eight bits — the same encoding as in the previous chapter, repeated here so you can check the simulator line by line:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;111 110 101 100 011 010 001 000&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 0 0 0 1 1 1 1 0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Start from one active cell and repeatedly apply that rule.&lt;/p&gt;</description></item><item><title>Rule 110 and Computation in a Grid</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/05-chapter/</link><pubDate>Mon, 10 Aug 2026 18:24:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/05-chapter/</guid><description>&lt;p&gt;Rule 110 looks like another one-byte transition table.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;111 110 101 100 011 010 001 000&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 0 1 1 0 1 1 1 0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But its behavior gives us a much deeper idea: a cellular automaton can become a computational medium.&lt;/p&gt;&#10;&lt;p&gt;The important shift is this:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;pattern generator&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;signal system&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;computation&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Rule 110 is computationally universal — under suitable encodings and initial conditions. Matthew Cook published the universality proof in &lt;em&gt;Complex Systems&lt;/em&gt; in 2004, settling a conjecture Wolfram had made in the mid-1980s: this elementary one-dimensional automaton can emulate universal computation.&lt;/p&gt;</description></item><item><title>Conway's Game of Life</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/06-chapter/</link><pubDate>Mon, 10 Aug 2026 18:25:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/06-chapter/</guid><description>&lt;p&gt;The previous chapter ended on a limit of one dimension: time supplies the second visual axis, but structures cannot move &lt;em&gt;inside&lt;/em&gt; the world. In two dimensions they can. Conway&amp;rsquo;s Game of Life is one of the cleanest examples of intricate two-dimensional behavior emerging from a tiny local rule.&lt;/p&gt;&#10;&lt;p&gt;John Conway devised it in 1970; Martin Gardner&amp;rsquo;s October 1970 &lt;em&gt;Scientific American&lt;/em&gt; column introduced it to a wide audience and triggered the volunteer zoology of patterns — still lifes, oscillators, spaceships — that made Life the most studied cellular automaton in history.&lt;/p&gt;</description></item><item><title>Patterns as Data — Oscillators, Spaceships and Gliders</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/07-chapter/</link><pubDate>Mon, 10 Aug 2026 18:26:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/07-chapter/</guid><description>&lt;p&gt;Once we can run Conway&amp;rsquo;s Game of Life, the next step is not to add more graphics.&lt;/p&gt;&#10;&lt;p&gt;It is to make the patterns themselves inspectable.&lt;/p&gt;&#10;&lt;p&gt;A blinker is not interesting because somebody named it.&lt;/p&gt;&#10;&lt;p&gt;It is interesting because it returns to the same state after two generations — a testable dynamical property, not an aesthetic judgment. Throughout this chapter, &amp;ldquo;interesting&amp;rdquo; always cashes out into something executable: a period, a displacement, a fingerprint match.&lt;/p&gt;</description></item><item><title>Beyond Conway — Life-like and Multi-State Rules</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/08-chapter/</link><pubDate>Mon, 10 Aug 2026 18:27:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/08-chapter/</guid><description>&lt;p&gt;The previous chapter ended on a causal direction: the rule produces the structures, and only then do we give the structures names. Change the rule and the names change with it.&lt;/p&gt;&#10;&lt;p&gt;That matters because Conway&amp;rsquo;s Game of Life is famous enough that it can accidentally become the definition of cellular automata.&lt;/p&gt;&#10;&lt;p&gt;It is not.&lt;/p&gt;&#10;&lt;p&gt;Life is one point in a much larger design space.&lt;/p&gt;&#10;&lt;p&gt;Keep the same two-dimensional grid and the same eight-cell Moore neighborhood, then change only the birth and survival counts.&lt;/p&gt;</description></item><item><title>Add Randomness Without Losing the Model</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/09-chapter/</link><pubDate>Mon, 10 Aug 2026 18:34:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/09-chapter/</guid><description>&lt;p&gt;So far every transition in the book has been deterministic.&lt;/p&gt;&#10;&lt;p&gt;Given the same state, the next state is fixed.&lt;/p&gt;&#10;&lt;p&gt;That makes deterministic automata unusually easy to debug: if we preserve the initial condition and rule, we preserve the trajectory.&lt;/p&gt;&#10;&lt;p&gt;But many useful models need another ingredient.&lt;/p&gt;&#10;&lt;p&gt;A tree may ignite.&lt;/p&gt;&#10;&lt;p&gt;An organism may reproduce.&lt;/p&gt;&#10;&lt;p&gt;A driver may hesitate.&lt;/p&gt;&#10;&lt;p&gt;A material defect may appear.&lt;/p&gt;&#10;&lt;p&gt;The local rule can still be precise even when the outcome is probabilistic.&lt;/p&gt;</description></item><item><title>Build a Forest Fire Simulation</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/10-chapter/</link><pubDate>Mon, 10 Aug 2026 18:36:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/10-chapter/</guid><description>&lt;p&gt;The previous chapter put probability into the rule. A forest fire is almost an ideal first exercise for using it.&lt;/p&gt;&#10;&lt;p&gt;The visible states are obvious:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;0 = empty&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;1 = tree&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;2 = burning&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The interactions are local.&lt;/p&gt;&#10;&lt;p&gt;And small changes in fuel density or ignition assumptions can produce very different global outcomes.&lt;/p&gt;&#10;&lt;p&gt;This is not intended as a high-fidelity wildfire model.&lt;/p&gt;&#10;&lt;p&gt;It is a deliberately simplified &lt;strong&gt;spread model&lt;/strong&gt; designed to isolate one mechanism:&lt;/p&gt;</description></item><item><title>Simulate Traffic with Rule 184</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/11-chapter/</link><pubDate>Mon, 10 Aug 2026 18:38:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/11-chapter/</guid><description>&lt;p&gt;The forest fire consumed its fuel. Rule 184 is the opposite case: a conserved quantity that moves. It is also a clean example of going from an abstract rule table to a model with a concrete interpretation.&lt;/p&gt;&#10;&lt;p&gt;Use a one-dimensional ring road:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;1 = car&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;0 = empty road&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A car moves one cell to the right when the destination is empty.&lt;/p&gt;&#10;&lt;p&gt;That is enough to produce free flow, queues and a macroscopic density-flow relationship.&lt;/p&gt;</description></item><item><title>Diffusion as Local Exchange</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/12-chapter/</link><pubDate>Mon, 10 Aug 2026 18:40:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/12-chapter/</guid><description>&lt;p&gt;Until now most cells have stored discrete state:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;0 / 1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;empty / tree / fire&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;road / car&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now let each cell store a continuous quantity.&lt;/p&gt;&#10;&lt;p&gt;For diffusion:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;state[y, x] = concentration&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The local transition is no longer birth, death or movement.&lt;/p&gt;&#10;&lt;p&gt;It is local exchange.&lt;/p&gt;&#10;&lt;p&gt;This steps outside the strict finite-state definition — a deliberate extension, flagged as such, that the book will keep developing through reaction-diffusion, Lenia, and learned automata.&lt;/p&gt;</description></item><item><title>Reaction-Diffusion and Pattern Formation</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/13-chapter/</link><pubDate>Mon, 10 Aug 2026 18:42:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/13-chapter/</guid><description>&lt;p&gt;Diffusion smooths differences.&lt;/p&gt;&#10;&lt;p&gt;Reaction can amplify them.&lt;/p&gt;&#10;&lt;p&gt;Put the two processes together and a nearly uniform field can develop persistent spots, stripes and fronts.&lt;/p&gt;&#10;&lt;p&gt;We will use a discrete Gray-Scott reaction-diffusion simulation because it gives us a compact bridge from local cellular updates to continuous pattern-forming dynamics. The model originates with Gray and Scott&amp;rsquo;s autocatalytic chemistry; John Pearson&amp;rsquo;s 1993 &lt;em&gt;Science&lt;/em&gt; paper showed that finite-amplitude perturbations of it produce a surprising variety of spatiotemporal patterns — which is exactly the experiment this chapter runs.&lt;/p&gt;</description></item><item><title>Build a Predator-Prey Ecosystem</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/14-chapter/</link><pubDate>Mon, 10 Aug 2026 18:44:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/14-chapter/</guid><description>&lt;p&gt;Gray-Scott, like the forest fire, transforms each cell in place.&lt;/p&gt;&#10;&lt;p&gt;Rule 184 moves occupancy, but in one constrained direction.&lt;/p&gt;&#10;&lt;p&gt;An ecosystem adds a harder problem:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;organisms move&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;organisms reproduce&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;predators consume prey&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;several organisms may want one destination&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now local intentions can conflict.&lt;/p&gt;&#10;&lt;p&gt;That means update semantics become part of the model.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="separate-visible-kind-from-internal-state"&gt;Separate visible kind from internal state&lt;/h2&gt;&#10;&lt;p&gt;Start with:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;0 = empty&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;1 = prey&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;2 = predator&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; numpy &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; np&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;EMPTY &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;PREY &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;PREDATOR &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kind &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;zeros(&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#ae81ff"&gt;100&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;100&lt;/span&gt;),&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dtype&lt;span style="color:#f92672"&gt;=&lt;/span&gt;np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;uint8,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A richer model may need predator energy, age or reproduction state.&lt;/p&gt;</description></item><item><title>Generate Caves from Noise</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/15-chapter/</link><pubDate>Mon, 10 Aug 2026 18:46:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/15-chapter/</guid><description>&lt;p&gt;A cave generator can be built from a mechanism we already understand:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;random initial cells&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ↓&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;count nearby walls&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ↓&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;apply local smoothing rule&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ↓&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;repeat a few times&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ↓&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;stop and use the result&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Unlike a forest-fire simulation, we are not trying to model an indefinitely evolving world.&lt;/p&gt;&#10;&lt;p&gt;Here the cellular automaton is a &lt;strong&gt;construction process&lt;/strong&gt;.&lt;/p&gt;&#10;&lt;p&gt;The smoothing rule below belongs to a documented family: roguelike developers call the classic form the 4-5 rule — a tile becomes a wall if its 3×3 neighborhood (counting itself) holds at least 5 walls — usually run from ~45% initial fill for about five iterations. This chapter uses a stricter one-threshold variant; the Research section traces the lineage and the parameter consequences.&lt;/p&gt;</description></item><item><title>Grow Terrain from Local Height Rules</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/16-chapter/</link><pubDate>Mon, 10 Aug 2026 18:48:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/16-chapter/</guid><description>&lt;p&gt;Binary caves ask:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;wall or floor?&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Terrain needs richer state.&lt;/p&gt;&#10;&lt;p&gt;Let each cell store a height:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;0.0 = low&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;1.0 = high&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now local rules can smooth, raise, erode and classify terrain.&lt;/p&gt;&#10;&lt;p&gt;The challenge is not creating a pretty array.&lt;/p&gt;&#10;&lt;p&gt;It is creating a process whose output we can explain and control.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="start-with-a-height-field"&gt;Start with a height field&lt;/h2&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; numpy &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; np&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;random_heightmap&lt;/span&gt;(&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; rows&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;120&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cols&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;160&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; seed&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;42&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; rng &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;random&lt;span style="color:#f92672"&gt;.&lt;/span&gt;default_rng(seed)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; rng&lt;span style="color:#f92672"&gt;.&lt;/span&gt;random(&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (rows, cols)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Raw independent noise contains variation but little large-scale geography.&lt;/p&gt;</description></item><item><title>Generate Textures with Local Rules</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/17-chapter/</link><pubDate>Mon, 10 Aug 2026 18:50:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/17-chapter/</guid><description>&lt;p&gt;Cellular automata do not need to represent a literal physical system.&lt;/p&gt;&#10;&lt;p&gt;They can also be used as visual machines.&lt;/p&gt;&#10;&lt;p&gt;The same ingredients we have used throughout the book:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;local state&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;neighborhood perception&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;shared update&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;repetition&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;can generate masks, growth patterns, surface variation and animation.&lt;/p&gt;&#10;&lt;p&gt;The evaluation question changes.&lt;/p&gt;&#10;&lt;p&gt;Instead of asking:&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;Is this physically accurate?&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;we ask:&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;Does this local process produce useful, controllable visual structure?&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;That still demands more than &amp;ldquo;it looks interesting&amp;rdquo; — and this chapter&amp;rsquo;s metrics section holds it to that standard.&lt;/p&gt;</description></item><item><title>Measure a Cellular Automaton</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/18-chapter/</link><pubDate>Mon, 10 Aug 2026 18:50:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/18-chapter/</guid><description>&lt;p&gt;Up to this point we have mostly &lt;strong&gt;looked at&lt;/strong&gt; cellular automata.&lt;/p&gt;&#10;&lt;p&gt;That is useful.&lt;/p&gt;&#10;&lt;p&gt;It is also limiting. Part II closed by asking how we tell which worlds are dynamically interesting, and looking cannot answer that at scale.&lt;/p&gt;&#10;&lt;p&gt;A human can inspect a handful of spacetime diagrams.&lt;/p&gt;&#10;&lt;p&gt;We cannot reliably inspect:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;256 elementary rules&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;× several initial conditions&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;× several widths&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;× hundreds of generations&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;× repeated stochastic runs&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;by eye.&lt;/p&gt;</description></item><item><title>Activity, Density and Change</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/19-chapter/</link><pubDate>Mon, 10 Aug 2026 18:51:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/19-chapter/</guid><description>&lt;p&gt;A cellular automaton can look busy while doing very little that persists.&lt;/p&gt;&#10;&lt;p&gt;It can also look visually quiet while preserving a small moving structure for hundreds of generations.&lt;/p&gt;&#10;&lt;p&gt;So we need to separate several properties that are easy to confuse:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;occupancy&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;temporal change&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;spatial variation&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;persistence&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The first three are owned by the previous chapter — &lt;code&gt;density&lt;/code&gt;, &lt;code&gt;change_rate&lt;/code&gt;/&lt;code&gt;change_curve&lt;/code&gt; (our activity observable), and &lt;code&gt;spatial_variation&lt;/code&gt; — and are reused here without redefinition. This chapter adds what they cannot see: whether change persists, where it happens, and how runs end.&lt;/p&gt;</description></item><item><title>Entropy and Information</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/20-chapter/</link><pubDate>Mon, 10 Aug 2026 18:52:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/20-chapter/</guid><description>&lt;p&gt;A row with almost all zeros is highly predictable.&lt;/p&gt;&#10;&lt;p&gt;A row containing a balanced mixture of zeros and ones is less predictable.&lt;/p&gt;&#10;&lt;p&gt;Shannon entropy gives us a precise way to measure that uncertainty — defined by Claude Shannon in 1948 as the expected surprise of a distribution, measured here in bits (base 2).&lt;/p&gt;&#10;&lt;p&gt;This chapter formally owns what Chapter 3 previewed: the preview &lt;code&gt;binary_entropy&lt;/code&gt; becomes the definition below, with the base convention, edge cases, and limitations stated properly.&lt;/p&gt;</description></item><item><title>Periodicity and Attractors</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/21-chapter/</link><pubDate>Mon, 10 Aug 2026 18:53:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/21-chapter/</guid><description>&lt;p&gt;Many cellular automata eventually repeat.&lt;/p&gt;&#10;&lt;p&gt;A fixed point repeats every generation.&lt;/p&gt;&#10;&lt;p&gt;An oscillator repeats after several generations.&lt;/p&gt;&#10;&lt;p&gt;On a finite grid, deterministic cellular automata must eventually revisit a previous state because only finitely many states exist.&lt;/p&gt;&#10;&lt;p&gt;That makes cycle detection a fundamental measurement: where entropy asked how uncertain a state is, recurrence asks whether the dynamics ever come back.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="hash-each-state"&gt;Hash each state&lt;/h2&gt;&#10;&lt;p&gt;For binary arrays we can store the bytes:&lt;/p&gt;</description></item><item><title>Sensitivity to Initial Conditions</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/22-chapter/</link><pubDate>Mon, 10 Aug 2026 18:54:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/22-chapter/</guid><description>&lt;p&gt;Change one cell.&lt;/p&gt;&#10;&lt;p&gt;Then run the same rule twice.&lt;/p&gt;&#10;&lt;p&gt;If the two futures remain almost identical, the rule is insensitive to that perturbation.&lt;/p&gt;&#10;&lt;p&gt;If the difference spreads, the rule amplifies local uncertainty.&lt;/p&gt;&#10;&lt;p&gt;That is one of the cleanest experiments we can perform on a cellular automaton.&lt;/p&gt;&#10;&lt;p&gt;One language note up front: this chapter says &amp;ldquo;sensitive&amp;rdquo; and &amp;ldquo;irregular,&amp;rdquo; never &amp;ldquo;chaotic&amp;rdquo; in the formal dynamical-systems sense. Whether any cellular automaton earns that stronger word is a classification question for the next chapter, which owns the class vocabulary.&lt;/p&gt;</description></item><item><title>Classify Rule Behavior</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/23-chapter/</link><pubDate>Mon, 10 Aug 2026 18:55:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/23-chapter/</guid><description>&lt;p&gt;We now have six kinds of measurement. The literature already offers a coarser tool for organizing rules: four broad behavioral classes.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Class I -&amp;gt; settles to homogeneous behavior&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Class II -&amp;gt; settles to simple stable or periodic structures&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Class III -&amp;gt; irregular, apparently random behavior&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Class IV -&amp;gt; persistent local structures and complex interactions&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;These labels are useful vocabulary — phenomenological shorthand from Wolfram&amp;rsquo;s 1980s survey, not formal dynamical-systems theorems. &amp;ldquo;Class III&amp;rdquo; here means &lt;em&gt;Wolfram-class&lt;/em&gt; irregularity, not proven chaos in the mathematical sense; the book has called Rule 30 &amp;ldquo;irregular&amp;rdquo; until now for exactly this reason, and this chapter does not upgrade that word.&lt;/p&gt;</description></item><item><title>Search All 256 Elementary Rules</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/24-chapter/</link><pubDate>Mon, 10 Aug 2026 18:56:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/24-chapter/</guid><description>&lt;p&gt;Elementary cellular automata give us a rare luxury.&lt;/p&gt;&#10;&lt;p&gt;The complete rule space is tiny.&lt;/p&gt;&#10;&lt;p&gt;There are only:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;256 rules&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So we do not need sampling, intuition or famous examples.&lt;/p&gt;&#10;&lt;p&gt;We can evaluate every rule.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="build-an-experiment-runner"&gt;Build an experiment runner&lt;/h2&gt;&#10;&lt;p&gt;Reuse the owned helpers with their real signatures — Chapter 18&amp;rsquo;s runner (rule number, width, generations, seed, single-or-random start) and Chapter 19&amp;rsquo;s fingerprint:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;scan_rules&lt;/span&gt;(width&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;201&lt;/span&gt;, generations&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;200&lt;/span&gt;):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; records &lt;span style="color:#f92672"&gt;=&lt;/span&gt; []&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; rule &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(&lt;span style="color:#ae81ff"&gt;256&lt;/span&gt;):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; history &lt;span style="color:#f92672"&gt;=&lt;/span&gt; run_rule(&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; rule,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; width&lt;span style="color:#f92672"&gt;=&lt;/span&gt;width,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; generations&lt;span style="color:#f92672"&gt;=&lt;/span&gt;generations,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; record &lt;span style="color:#f92672"&gt;=&lt;/span&gt; fingerprint(history)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; record[&lt;span style="color:#e6db74"&gt;&amp;#34;rule&amp;#34;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; rule&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; record[&lt;span style="color:#e6db74"&gt;&amp;#34;mean_entropy&amp;#34;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; float(&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; entropy_curve(history)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;mean()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; record[&lt;span style="color:#e6db74"&gt;&amp;#34;compression_ratio&amp;#34;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; compression_ratio(&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; history&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; record&lt;span style="color:#f92672"&gt;.&lt;/span&gt;update(recurrence_metrics(history))&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; records&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append(record)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; records&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The hard part is no longer execution.&lt;/p&gt;</description></item><item><title>Search Larger Rule Spaces</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/25-chapter/</link><pubDate>Mon, 10 Aug 2026 18:57:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/25-chapter/</guid><description>&lt;p&gt;The 256 elementary rules are small enough to enumerate.&lt;/p&gt;&#10;&lt;p&gt;Most interesting cellular-automata design spaces are not.&lt;/p&gt;&#10;&lt;p&gt;Add more states, a larger neighborhood, continuous parameters, or several channels and exhaustive search quickly becomes impossible.&lt;/p&gt;&#10;&lt;p&gt;So we need search strategies.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="why-the-rule-space-explodes"&gt;Why the rule space explodes&lt;/h2&gt;&#10;&lt;p&gt;For &lt;code&gt;k&lt;/code&gt; possible cell states and a neighborhood containing &lt;code&gt;n&lt;/code&gt; cells, there are:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;k^n possible neighborhood configurations&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A deterministic rule chooses one of &lt;code&gt;k&lt;/code&gt; outputs for every configuration, giving:&lt;/p&gt;</description></item><item><title>Evolve Rules for Desired Behavior</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/26-chapter/</link><pubDate>Mon, 10 Aug 2026 18:58:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/26-chapter/</guid><description>&lt;p&gt;Once we can represent a rule, mutate it and measure its behavior, we can evolve cellular automata.&lt;/p&gt;&#10;&lt;p&gt;The key idea is simple:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;population of rules&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ↓&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;simulate&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ↓&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;measure&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ↓&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;select&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ↓&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mutate&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ↓&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;repeat&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This chapter builds that loop without hiding it behind an optimization framework. &amp;ldquo;Evolution&amp;rdquo; here is algorithmic — genomes, mutation, selection over rule bits — not a biological claim. The genotype is eight bits; the phenotype is the measured trajectory.&lt;/p&gt;</description></item><item><title>Cellular Automata as Computation</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/27-chapter/</link><pubDate>Mon, 10 Aug 2026 18:59:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/27-chapter/</guid><description>&lt;p&gt;A cellular automaton is a state machine distributed across space.&lt;/p&gt;&#10;&lt;p&gt;Each cell reads local information, applies the same transition rule, and writes a new state.&lt;/p&gt;&#10;&lt;p&gt;That is computation in the thin sense: deterministic state transformation. Every automaton in this book computes, in that sense, every step it runs.&lt;/p&gt;&#10;&lt;p&gt;The deeper question — and the one this chapter formally owns — is whether local patterns can carry, transform and combine information in a way that supports &lt;em&gt;general&lt;/em&gt; computation. Chapter 5 gave the first exposure through Rule 110&amp;rsquo;s gliders; here universality becomes a precise comparative property rather than an impressive example.&lt;/p&gt;</description></item><item><title>From Discrete Cells to Continuous State</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/28-chapter/</link><pubDate>Mon, 10 Aug 2026 19:43:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/28-chapter/</guid><description>&lt;p&gt;So far most of our cellular automata have used a small set of states:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;0 or 1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;empty / prey / predator&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ready / firing / refractory&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That makes rules easy to inspect.&lt;/p&gt;&#10;&lt;p&gt;But it also forces every update to make a hard categorical decision.&lt;/p&gt;&#10;&lt;p&gt;What happens if a cell can instead hold &lt;strong&gt;any value between 0 and 1&lt;/strong&gt;?&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;0.0 -------------------------- 1.0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now a cell can represent intensity, density, concentration, activation or some abstract amount of local material.&lt;/p&gt;</description></item><item><title>Neighborhoods as Convolution Kernels</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/29-chapter/</link><pubDate>Mon, 10 Aug 2026 19:45:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/29-chapter/</guid><description>&lt;p&gt;A neighborhood does not have to be a list of nearby coordinates.&lt;/p&gt;&#10;&lt;p&gt;It can be a &lt;strong&gt;spatial weighting function&lt;/strong&gt;.&lt;/p&gt;&#10;&lt;p&gt;That lets us say:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cells near this radius matter a lot&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cells closer in matter less&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cells farther away do not matter at all&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The standard programming tool for applying that same weighted neighborhood everywhere is convolution.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="start-with-a-small-kernel"&gt;Start with a small kernel&lt;/h2&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; numpy &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; np&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kernel &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;array([&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [&lt;span style="color:#ae81ff"&gt;0.0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.0&lt;/span&gt;],&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [&lt;span style="color:#ae81ff"&gt;0.1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.6&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.1&lt;/span&gt;],&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [&lt;span style="color:#ae81ff"&gt;0.0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.0&lt;/span&gt;],&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;])&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Normalize it:&lt;/p&gt;</description></item><item><title>Growth Functions</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/30-chapter/</link><pubDate>Mon, 10 Aug 2026 19:48:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/30-chapter/</guid><description>&lt;p&gt;We now have two pieces:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;continuous state&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ↓&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;weighted neighborhood&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But a neighborhood value does not tell us what should happen next.&lt;/p&gt;&#10;&lt;p&gt;We need a response curve.&lt;/p&gt;&#10;&lt;p&gt;In Lenia-style systems that curve is usually called a &lt;strong&gt;growth function&lt;/strong&gt;.&lt;/p&gt;&#10;&lt;p&gt;It converts neighborhood potential into local growth or decay. This generalizes Chapter 28&amp;rsquo;s &lt;code&gt;growth_function&lt;/code&gt;: same Gaussian-bump shape, now with explicit &lt;code&gt;mu&lt;/code&gt; (preferred density) and &lt;code&gt;sigma&lt;/code&gt; (tolerance) parameters instead of fixed constants.&lt;/p&gt;</description></item><item><title>Build Lenia From First Principles</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/31-chapter/</link><pubDate>Mon, 10 Aug 2026 19:51:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/31-chapter/</guid><description>&lt;p&gt;We now have every conceptual component needed for a minimal Lenia implementation:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;continuous state&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;radial kernel&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;convolution&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;smooth growth function&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;small time step&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;bounded update&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This chapter assembles them into one runnable system — one historically important system, due to Bert Wang-Chak Chan (&amp;ldquo;Lenia: Biology of Artificial Life,&amp;rdquo; Complex Systems 28(3), 2019): not generic continuous CA, but Lenia specifically. The framing for this part so far:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Ch28–30&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;= components&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Ch31&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;= one historically important system built from those components&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;&#10;&lt;h2 id="fidelity-statement"&gt;Fidelity statement&lt;/h2&gt;&#10;&lt;p&gt;The engine below implements the canonical Lenia update exactly — state plus timestep-scaled growth of the convolved field, clipped to [0, 1] — with the exponential growth mapping from Chan&amp;rsquo;s paper. It differs from full Lenia in scope, stated here so later comparisons use the same baseline:&lt;/p&gt;</description></item><item><title>Discover Your First Lenia Organisms</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/32-chapter/</link><pubDate>Mon, 10 Aug 2026 19:54:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/32-chapter/</guid><description>&lt;p&gt;Running Lenia is easy.&lt;/p&gt;&#10;&lt;p&gt;Finding persistent, localized, non-trivial structures is the hard part.&lt;/p&gt;&#10;&lt;p&gt;This chapter turns that problem into a repeatable search pipeline. It follows Chan&amp;rsquo;s discovery playbook structurally — random soup generation, survival filtering, parameter tweaking, and, crucially, human judgment for what counts as interesting — while automating the parts that do not need eyes.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="define-what-counts-as-a-candidate"&gt;Define what counts as a candidate&lt;/h2&gt;&#10;&lt;p&gt;We should not start with the vague objective:&lt;/p&gt;</description></item><item><title>Search Lenia Parameter Space</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/33-chapter/</link><pubDate>Mon, 10 Aug 2026 19:57:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/33-chapter/</guid><description>&lt;p&gt;A Lenia pattern is not defined by its initial state alone.&lt;/p&gt;&#10;&lt;p&gt;It also lives inside a particular dynamical world.&lt;/p&gt;&#10;&lt;p&gt;Change the kernel or growth function slightly and the same seed may:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;die&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;explode&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;freeze&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;oscillate&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;move&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;split&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;stabilize into a different morphology&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So discovery has two coupled search spaces:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;initial condition&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; +&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;world parameters&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;&#10;&lt;h2 id="define-parameter-ranges"&gt;Define parameter ranges&lt;/h2&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;PARAM_RANGES &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;radius&amp;#34;&lt;/span&gt;: (&lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;24&lt;/span&gt;),&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;ring_center&amp;#34;&lt;/span&gt;: (&lt;span style="color:#ae81ff"&gt;0.25&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.75&lt;/span&gt;),&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;ring_width&amp;#34;&lt;/span&gt;: (&lt;span style="color:#ae81ff"&gt;0.05&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.25&lt;/span&gt;),&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;mu&amp;#34;&lt;/span&gt;: (&lt;span style="color:#ae81ff"&gt;0.05&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.30&lt;/span&gt;),&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;sigma&amp;#34;&lt;/span&gt;: (&lt;span style="color:#ae81ff"&gt;0.01&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.08&lt;/span&gt;),&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;dt&amp;#34;&lt;/span&gt;: (&lt;span style="color:#ae81ff"&gt;0.03&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.20&lt;/span&gt;),&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;These ranges are experimental choices.&lt;/p&gt;</description></item><item><title>Multi-Kernel and Multi-Channel Lenia</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/34-chapter/</link><pubDate>Mon, 10 Aug 2026 20:00:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/34-chapter/</guid><description>&lt;p&gt;Our Lenia implementation has one scalar field:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;A(x, y)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and one kernel:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;K&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That is enough for rich behavior.&lt;/p&gt;&#10;&lt;p&gt;But it also forces every local process to share the same spatial scale and the same state variable.&lt;/p&gt;&#10;&lt;p&gt;A richer model can use multiple channels:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;A0(x, y)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;A1(x, y)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;A2(x, y)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and multiple kernels linking them.&lt;/p&gt;&#10;&lt;p&gt;This chapter builds a pedagogical multi-channel formulation in Lenia&amp;rsquo;s spirit — a connection graph with per-edge kernels and growth parameters. Canonical multi-kernel, multi-channel Lenia is Chan&amp;rsquo;s &amp;ldquo;Expanded Universe&amp;rdquo; (ALIFE 2020) direction; the book&amp;rsquo;s version is simpler and says so, keeping the graph inspectable rather than matching the canonical matrix formulation.&lt;/p&gt;</description></item><item><title>Damage, Robustness and Persistence</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/35-chapter/</link><pubDate>Mon, 10 Aug 2026 20:03:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/35-chapter/</guid><description>&lt;p&gt;A pattern that survives in perfect conditions is only the beginning.&lt;/p&gt;&#10;&lt;p&gt;A stronger artificial-life question is:&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;What happens when the pattern is disturbed?&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;We can turn that into an experiment.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="define-damage-explicitly"&gt;Define damage explicitly&lt;/h2&gt;&#10;&lt;p&gt;Start with a rectangular ablation:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;damage_rectangle&lt;/span&gt;(state, y0, y1, x0, x1):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; damaged &lt;span style="color:#f92672"&gt;=&lt;/span&gt; state&lt;span style="color:#f92672"&gt;.&lt;/span&gt;copy()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; damaged[&lt;span style="color:#f92672"&gt;...&lt;/span&gt;, y0:y1, x0:x1] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.0&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; damaged&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For a single-channel state:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;damaged &lt;span style="color:#f92672"&gt;=&lt;/span&gt; damage_rectangle(state, &lt;span style="color:#ae81ff"&gt;55&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;70&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;55&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;70&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For multi-channel state, the ellipsis damages all channels in the same spatial region.&lt;/p&gt;</description></item><item><title>Flow-Lenia and Mass-Conserving Artificial Life</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/36-chapter/</link><pubDate>Mon, 10 Aug 2026 20:06:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/36-chapter/</guid><description>&lt;p&gt;Ordinary Lenia updates local state by adding growth:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;A(t + dt) = clip(A(t) + dt × G(U))&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That means state can be created in one region and destroyed in another.&lt;/p&gt;&#10;&lt;p&gt;For many artificial-life experiments that is perfectly acceptable.&lt;/p&gt;&#10;&lt;p&gt;But it leaves a major question:&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;What changes if local structure must reorganize &lt;strong&gt;existing mass&lt;/strong&gt; instead of creating or deleting it?&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;Flow-Lenia — Plantec et al. (2023), &amp;ldquo;Flow-Lenia: Towards open-ended evolution in cellular automata through mass conservation and parameter localization&amp;rdquo; — explores exactly that direction through two ideas: reformulating the update around transport so mass is conserved, and embedding rule parameters as local fields rather than global constants. This chapter presents both ideas with small pedagogical models, honestly labeled as stepping stones rather than reproductions.&lt;/p&gt;</description></item><item><title>Make the Automaton Differentiable</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/37-chapter/</link><pubDate>Mon, 10 Aug 2026 20:31:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/37-chapter/</guid><description>&lt;p&gt;So far every rule in this book has been chosen by us.&lt;/p&gt;&#10;&lt;p&gt;Even Lenia still asks us to decide the neighborhood kernel, the growth function and the parameters that connect them.&lt;/p&gt;&#10;&lt;p&gt;What if we stop designing the local rule directly?&lt;/p&gt;&#10;&lt;p&gt;What if we define only the &lt;strong&gt;goal&lt;/strong&gt;, then let gradient descent discover a local update rule that achieves it? (Designed here, learned starting now — Chapter 36&amp;rsquo;s bridge sentence becomes this chapter&amp;rsquo;s premise.)&lt;/p&gt;</description></item><item><title>Learn the Local Update Rule</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/38-chapter/</link><pubDate>Mon, 10 Aug 2026 20:32:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/38-chapter/</guid><description>&lt;p&gt;A neural cellular automaton does not need a large neural network.&lt;/p&gt;&#10;&lt;p&gt;It needs a &lt;strong&gt;small local network applied everywhere&lt;/strong&gt;.&lt;/p&gt;&#10;&lt;p&gt;That distinction matters.&lt;/p&gt;&#10;&lt;p&gt;The capability of the system comes less from the size of one cell&amp;rsquo;s computation and more from the repeated interaction of many cells over time. (Not &amp;ldquo;intelligence&amp;rdquo; — computational capacity through recurrence, in the book&amp;rsquo;s established vocabulary.)&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="perception-first"&gt;Perception first&lt;/h2&gt;&#10;&lt;p&gt;Each cell needs information about itself and nearby cells.&lt;/p&gt;</description></item><item><title>Hidden Cell Channels and Local Memory</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/39-chapter/</link><pubDate>Mon, 10 Aug 2026 20:34:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/39-chapter/</guid><description>&lt;p&gt;A visible pixel is not enough state for a cell that must also coordinate growth.&lt;/p&gt;&#10;&lt;p&gt;So give every cell a vector.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[R, G, B, alpha, h1, h2, ... h12]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The first channels can be rendered. The rest are private internal state. (Chapter 37 deferred hidden-channel ownership here; this chapter takes it.)&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;CHANNELS &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;16&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;VISIBLE &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;state &lt;span style="color:#f92672"&gt;=&lt;/span&gt; torch&lt;span style="color:#f92672"&gt;.&lt;/span&gt;zeros(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, CHANNELS, &lt;span style="color:#ae81ff"&gt;64&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;64&lt;/span&gt;, device&lt;span style="color:#f92672"&gt;=&lt;/span&gt;DEVICE)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The hidden channels have no labels. We do not tell the model that channel 8 means &amp;ldquo;distance from the center&amp;rdquo; or channel 11 means &amp;ldquo;grow east&amp;rdquo;. If useful internal signals exist, training must discover them.&lt;/p&gt;</description></item><item><title>Grow a Target From One Seed</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/40-chapter/</link><pubDate>Mon, 10 Aug 2026 20:35:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/40-chapter/</guid><description>&lt;p&gt;Now we can pose the central morphogenesis problem:&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;Start from one cell and learn local rules that construct a target pattern.&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;Note what this chapter is not: it is not asynchronous scheduling (that is the next chapter), nor persistence or regeneration training (later chapters own those objectives). One objective — growth to target — trained and honestly evaluated.&lt;/p&gt;&#10;&lt;h2 id="prepare-a-target"&gt;Prepare a target&lt;/h2&gt;&#10;&lt;p&gt;Assume an RGBA image has been loaded into a tensor:&lt;/p&gt;</description></item><item><title>Randomize the Update Schedule</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/41-chapter/</link><pubDate>Mon, 10 Aug 2026 20:36:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/41-chapter/</guid><description>&lt;p&gt;Most cellular automata in this book have used synchronous updates:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;all cells observe state_t&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;all cells update&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;state_t+1 appears&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Neural cellular automata are typically trained with randomized update schedules: there is no global clock, and cells cannot rely on exact phase relationships. The aim is robustness to timing, which we will measure rather than assume.&lt;/p&gt;&#10;&lt;h2 id="stochastic-firing"&gt;Stochastic firing&lt;/h2&gt;&#10;&lt;p&gt;Instead of applying every predicted update, sample a binary mask:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;stochastic_update&lt;/span&gt;(x, dx, fire_rate&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0.5&lt;/span&gt;):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; mask &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; torch&lt;span style="color:#f92672"&gt;.&lt;/span&gt;rand(&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; x&lt;span style="color:#f92672"&gt;.&lt;/span&gt;shape[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;], &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, x&lt;span style="color:#f92672"&gt;.&lt;/span&gt;shape[&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;], x&lt;span style="color:#f92672"&gt;.&lt;/span&gt;shape[&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;],&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; device&lt;span style="color:#f92672"&gt;=&lt;/span&gt;x&lt;span style="color:#f92672"&gt;.&lt;/span&gt;device,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ) &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; fire_rate&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; x &lt;span style="color:#f92672"&gt;+&lt;/span&gt; dx &lt;span style="color:#f92672"&gt;*&lt;/span&gt; mask&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Half the cells update on average.&lt;/p&gt;</description></item><item><title>Train for Persistence</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/42-chapter/</link><pubDate>Mon, 10 Aug 2026 20:37:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/42-chapter/</guid><description>&lt;p&gt;Growing a target once is not enough.&lt;/p&gt;&#10;&lt;p&gt;A useful self-organizing system should continue to satisfy its objective after it arrives.&lt;/p&gt;&#10;&lt;p&gt;That means the target should behave more like an &lt;strong&gt;attractor&lt;/strong&gt; than a timestamped frame. Operationally: low loss sustained over an extended interval past the growth horizon — not exact state invariance, not biological homeostasis.&lt;/p&gt;&#10;&lt;h2 id="the-failure-mode"&gt;The failure mode&lt;/h2&gt;&#10;&lt;p&gt;Suppose training always evaluates at step 64.&lt;/p&gt;&#10;&lt;p&gt;The model can learn:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;seed&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ↓&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;grow&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ↓&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;target at step 64&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ↓&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;overshoot&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ↓&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;disintegrate&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The loss never sees the failure after step 64.&lt;/p&gt;</description></item><item><title>Regenerate After Damage</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/43-chapter/</link><pubDate>Mon, 10 Aug 2026 20:38:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/43-chapter/</guid><description>&lt;p&gt;Persistence asks whether the organism can remain near its target.&lt;/p&gt;&#10;&lt;p&gt;Regeneration asks a different question:&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;after part of the state is destroyed, can local rules reconstruct the missing structure?&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;This is a much stronger test.&lt;/p&gt;&#10;&lt;h2 id="damage-the-state-not-just-the-image"&gt;Damage the state, not just the image&lt;/h2&gt;&#10;&lt;p&gt;If we erase only visible RGBA channels but leave hidden channels untouched, the model may retain a perfect invisible blueprint.&lt;/p&gt;&#10;&lt;p&gt;A harder test removes &lt;strong&gt;all channels&lt;/strong&gt; inside the damaged region.&lt;/p&gt;</description></item><item><title>Test Generalization Beyond Training</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/44-chapter/</link><pubDate>Mon, 10 Aug 2026 20:39:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/44-chapter/</guid><description>&lt;p&gt;A model can look robust while still depending on the exact conditions used during training.&lt;/p&gt;&#10;&lt;p&gt;So after growth, persistence and regeneration, we need a harder question:&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;what happens when the world changes?&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;h2 id="build-a-generalization-matrix"&gt;Build a generalization matrix&lt;/h2&gt;&#10;&lt;p&gt;Vary dimensions independently:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;canvas size&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;seed position&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;update rate&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rollout length&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;damage geometry&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;damage severity&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;noise level&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;boundary conditions&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then evaluate combinations that were not used during training. The table at the end of this chapter is executable scaffolding, not a report: every row specifies how to measure, and the verdicts get filled in by running, starting from one held-out axis at a time rather than all shifts at once.&lt;/p&gt;</description></item><item><title>Neural Cellular Automata for Pathfinding</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/45-chapter/</link><pubDate>Mon, 10 Aug 2026 20:37:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/45-chapter/</guid><description>&lt;p&gt;Until now our neural cellular automata have learned to &lt;strong&gt;make and maintain shapes&lt;/strong&gt;.&lt;/p&gt;&#10;&lt;p&gt;Now we will ask them to compute something.&lt;/p&gt;&#10;&lt;p&gt;Given:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;walls&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;start&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;finish&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;can a shared local update rule discover a path?&lt;/p&gt;&#10;&lt;p&gt;This is an unusually good task for an NCA because classical pathfinding already has a local interpretation — and because recent work (Earle et al., 2023) has shown both hand-coded and learned BFS/DFS inside the NCA framework, with generalization tested on harder distributions. That paper is this chapter&amp;rsquo;s running reference: it shows the task is learnable in that setup and sets the evaluation standard.&lt;/p&gt;</description></item><item><title>Learn to Solve Mazes</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/46-chapter/</link><pubDate>Mon, 10 Aug 2026 20:38:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/46-chapter/</guid><description>&lt;p&gt;A pathfinding NCA becomes interesting only when the training problem itself is disciplined.&lt;/p&gt;&#10;&lt;p&gt;If every maze has the same size, wall density and corridor style, the model may learn the dataset more than the algorithm.&lt;/p&gt;&#10;&lt;p&gt;So this chapter builds the training system around &lt;strong&gt;procedural variation&lt;/strong&gt;.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="generate-mazes-as-data"&gt;Generate mazes as data&lt;/h2&gt;&#10;&lt;p&gt;Start with binary occupancy:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;0 = open&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;1 = wall&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;One simple generator begins with random walls. It does not reject disconnected examples; the BFS teacher below marks unreachable cells with a mask instead.&lt;/p&gt;</description></item><item><title>Generalize to Harder and Larger Mazes</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/47-chapter/</link><pubDate>Mon, 10 Aug 2026 20:39:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/47-chapter/</guid><description>&lt;p&gt;Training accuracy answers the easiest question:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Can the model solve problems drawn from the training distribution?&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The more interesting question is:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Did the local rule learn a reusable computation?&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This chapter turns that into an explicit evaluation protocol.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="hold-out-dimensions-of-difficulty"&gt;Hold out dimensions of difficulty&lt;/h2&gt;&#10;&lt;p&gt;Instead of one validation set, create several test families.&lt;/p&gt;&#10;&lt;p&gt;For example:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;A: 32×32, familiar wall density&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;B: 48×48, familiar wall density&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;C: 64×64, familiar wall density&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;D: 32×32, denser obstacles&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;E: 32×32, longer required paths&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;F: different procedural maze generator&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;G: narrow bottlenecks and many dead ends&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The point is not to maximize one aggregate score.&lt;/p&gt;</description></item><item><title>Inspect Hidden-State Propagation</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/48-chapter/</link><pubDate>Mon, 10 Aug 2026 20:40:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/48-chapter/</guid><description>&lt;p&gt;A neural cellular automaton can solve a maze while most of its computation remains invisible.&lt;/p&gt;&#10;&lt;p&gt;The visible output might be one distance channel.&lt;/p&gt;&#10;&lt;p&gt;The internal state may contain eleven hidden channels (5–15 in the maze layout) evolving underneath it.&lt;/p&gt;&#10;&lt;p&gt;This chapter asks:&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;what is moving through those hidden channels while the answer is being computed?&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="capture-the-entire-state-trajectory"&gt;Capture the entire state trajectory&lt;/h2&gt;&#10;&lt;p&gt;Instead of saving only the final output — &lt;code&gt;rollout_frozen&lt;/code&gt; plus per-step recording, same clamped execution, now with a trace:&lt;/p&gt;</description></item><item><title>What Did the Neural CA Actually Learn?</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/49-chapter/</link><pubDate>Mon, 10 Aug 2026 20:41:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/49-chapter/</guid><description>&lt;p&gt;Visualization gives us hypotheses.&lt;/p&gt;&#10;&lt;p&gt;Intervention gives us evidence.&lt;/p&gt;&#10;&lt;p&gt;If we suspect a hidden channel carries useful information, the next question is simple:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;what happens if we remove it?&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This chapter turns NCA interpretability into controlled experimentation.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="establish-the-behavioral-baseline"&gt;Establish the behavioral baseline&lt;/h2&gt;&#10;&lt;p&gt;Before touching the model, record its normal performance — with a defined suite, not an anecdote:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;score_maze&lt;/span&gt;(final, walls, start, goal):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dist &lt;span style="color:#f92672"&gt;=&lt;/span&gt; final[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;]&lt;span style="color:#f92672"&gt;.&lt;/span&gt;detach()&lt;span style="color:#f92672"&gt;.&lt;/span&gt;cpu()&lt;span style="color:#f92672"&gt;.&lt;/span&gt;numpy()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; optimal_dist &lt;span style="color:#f92672"&gt;=&lt;/span&gt; bfs_distance(walls, goal)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#f92672"&gt;not&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;isfinite(optimal_dist[start]):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; (&lt;span style="color:#e6db74"&gt;&amp;#34;unreachable&amp;#34;&lt;/span&gt;, int(np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;all(dist &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.05&lt;/span&gt;)))&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; path &lt;span style="color:#f92672"&gt;=&lt;/span&gt; descend_path(dist, start, goal, walls)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; path[&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;] &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; goal:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; (&lt;span style="color:#e6db74"&gt;&amp;#34;unsolved&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; excess &lt;span style="color:#f92672"&gt;=&lt;/span&gt; len(path) &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; int(optimal_dist[start])&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; (&lt;span style="color:#e6db74"&gt;&amp;#34;solved&amp;#34;&lt;/span&gt;, excess)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;evaluate_suite&lt;/span&gt;(model, mazes, steps&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;128&lt;/span&gt;, runner&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; run &lt;span style="color:#f92672"&gt;=&lt;/span&gt; runner &lt;span style="color:#f92672"&gt;or&lt;/span&gt; rollout_frozen&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; solved &lt;span style="color:#f92672"&gt;=&lt;/span&gt; optimal &lt;span style="color:#f92672"&gt;=&lt;/span&gt; unreachable_ok &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; excess, unreachable &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [], &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; walls, start, goal &lt;span style="color:#f92672"&gt;in&lt;/span&gt; mazes:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; state &lt;span style="color:#f92672"&gt;=&lt;/span&gt; make_state(walls, start, goal)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; frozen &lt;span style="color:#f92672"&gt;=&lt;/span&gt; state&lt;span style="color:#f92672"&gt;.&lt;/span&gt;clone()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; final &lt;span style="color:#f92672"&gt;=&lt;/span&gt; run(model, state, steps, frozen)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; kind, value &lt;span style="color:#f92672"&gt;=&lt;/span&gt; score_maze(final, walls, start, goal)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; kind &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;unreachable&amp;#34;&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; unreachable &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; unreachable_ok &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; value&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;elif&lt;/span&gt; kind &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;solved&amp;#34;&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; solved &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; optimal &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; int(value &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; excess&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append(value)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; n &lt;span style="color:#f92672"&gt;=&lt;/span&gt; len(mazes) &lt;span style="color:#f92672"&gt;-&lt;/span&gt; unreachable&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;valid_path_rate&amp;#34;&lt;/span&gt;: solved &lt;span style="color:#f92672"&gt;/&lt;/span&gt; max(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, n),&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;optimal_path_rate&amp;#34;&lt;/span&gt;: optimal &lt;span style="color:#f92672"&gt;/&lt;/span&gt; max(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, n),&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;mean_excess&amp;#34;&lt;/span&gt;: float(np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;mean(excess)) &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; excess &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; float(&lt;span style="color:#e6db74"&gt;&amp;#34;nan&amp;#34;&lt;/span&gt;),&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;unreachable_accuracy&amp;#34;&lt;/span&gt;: unreachable_ok &lt;span style="color:#f92672"&gt;/&lt;/span&gt; max(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, unreachable),&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;(Verified: executes end to end on test mazes; an untrained stub scores zero throughout — the harness measures rather than flatters.)&lt;/p&gt;</description></item><item><title>Profile Before You Optimize</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/50-chapter/</link><pubDate>Mon, 10 Aug 2026 20:52:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/50-chapter/</guid><description>&lt;p&gt;By now we have built dozens of automata.&lt;/p&gt;&#10;&lt;p&gt;The natural temptation is to make them faster.&lt;/p&gt;&#10;&lt;p&gt;The wrong first question is:&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;Which optimization trick should I use?&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;The right first question is:&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;Where is the time actually going?&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;Performance work begins with measurement, and with the doctrine Part VI starts from:&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;&lt;strong&gt;Optimize the verified implementation, not the first implementation that happens to render something plausible.&lt;/strong&gt;&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;Running this book&amp;rsquo;s own earlier code turned up undefined helpers, wrong signatures and a misaligned FFT, all inside chapters that produced plausible figures. Speed means nothing until equivalence is established.&lt;/p&gt;</description></item><item><title>Vectorize the Update Loop</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/51-chapter/</link><pubDate>Mon, 10 Aug 2026 20:53:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/51-chapter/</guid><description>&lt;p&gt;A cellular automaton is local.&lt;/p&gt;&#10;&lt;p&gt;That does &lt;strong&gt;not&lt;/strong&gt; mean we should update it cell by cell in Python.&lt;/p&gt;&#10;&lt;p&gt;For dense grids, the same local rule is applied everywhere. That regularity is exactly what array programming is good at.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="start-with-the-obvious-implementation"&gt;Start with the obvious implementation&lt;/h2&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;life_step_slow&lt;/span&gt;(grid):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; height, width &lt;span style="color:#f92672"&gt;=&lt;/span&gt; grid&lt;span style="color:#f92672"&gt;.&lt;/span&gt;shape&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; next_grid &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;zeros_like(grid)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; y &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(height):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; x &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(width):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; total &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; dy &lt;span style="color:#f92672"&gt;in&lt;/span&gt; (&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; dx &lt;span style="color:#f92672"&gt;in&lt;/span&gt; (&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; dx &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#f92672"&gt;and&lt;/span&gt; dy &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;continue&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; total &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; grid[(y &lt;span style="color:#f92672"&gt;+&lt;/span&gt; dy) &lt;span style="color:#f92672"&gt;%&lt;/span&gt; height, (x &lt;span style="color:#f92672"&gt;+&lt;/span&gt; dx) &lt;span style="color:#f92672"&gt;%&lt;/span&gt; width]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; alive &lt;span style="color:#f92672"&gt;=&lt;/span&gt; grid[y, x] &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; next_grid[y, x] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; total &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt; &lt;span style="color:#f92672"&gt;or&lt;/span&gt; (alive &lt;span style="color:#f92672"&gt;and&lt;/span&gt; total &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; next_grid&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is useful because it states the mechanism clearly.&lt;/p&gt;</description></item><item><title>Run Cellular Automata on the GPU</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/52-chapter/</link><pubDate>Mon, 10 Aug 2026 20:54:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/52-chapter/</guid><description>&lt;p&gt;Once the update is expressed as tensor operations, moving to a GPU becomes straightforward.&lt;/p&gt;&#10;&lt;p&gt;But a GPU is not automatically faster.&lt;/p&gt;&#10;&lt;p&gt;It wins when there is enough parallel work to amortize transfer and launch overhead.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="a-tensor-implementation-of-life"&gt;A tensor implementation of Life&lt;/h2&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; torch&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; torch.nn.functional &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; F&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;LIFE_KERNEL &lt;span style="color:#f92672"&gt;=&lt;/span&gt; torch&lt;span style="color:#f92672"&gt;.&lt;/span&gt;tensor(&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [[&lt;span style="color:#ae81ff"&gt;1.0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1.0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1.0&lt;/span&gt;],&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [&lt;span style="color:#ae81ff"&gt;1.0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1.0&lt;/span&gt;],&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [&lt;span style="color:#ae81ff"&gt;1.0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1.0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1.0&lt;/span&gt;]]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;view(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;life_step&lt;/span&gt;(x):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; padded &lt;span style="color:#f92672"&gt;=&lt;/span&gt; F&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pad(x, (&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;), mode&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;circular&amp;#34;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; neighbors &lt;span style="color:#f92672"&gt;=&lt;/span&gt; F&lt;span style="color:#f92672"&gt;.&lt;/span&gt;conv2d(padded, LIFE_KERNEL&lt;span style="color:#f92672"&gt;.&lt;/span&gt;to(x&lt;span style="color:#f92672"&gt;.&lt;/span&gt;device))&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; alive &lt;span style="color:#f92672"&gt;=&lt;/span&gt; x &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.5&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; born &lt;span style="color:#f92672"&gt;=&lt;/span&gt; neighbors &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; survive &lt;span style="color:#f92672"&gt;=&lt;/span&gt; alive &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt; (neighbors &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; (born &lt;span style="color:#f92672"&gt;|&lt;/span&gt; survive)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;float()&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Two things matter here beyond the convolution. First, this is the third &lt;code&gt;life_step&lt;/code&gt; in the book (after Chapters 6 and 51) — same B3/S23 rule, new backend, bridged explicitly rather than silently redefined. Second, the padding mode is load-bearing: plain &lt;code&gt;padding=1&lt;/code&gt; zero-pads, which silently changes periodic boundaries into dead ones. Circular padding preserves the torus semantics every roll-based helper in this book assumes — verified bit-identical against the NumPy version on 20 random grids, where the zero-padded variant mismatched all 20 at the edges.&lt;/p&gt;</description></item><item><title>Use FFTs for Large Neighborhoods</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/53-chapter/</link><pubDate>Mon, 10 Aug 2026 20:55:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/53-chapter/</guid><description>&lt;p&gt;Small local neighborhoods are cheap to evaluate directly.&lt;/p&gt;&#10;&lt;p&gt;Large smooth kernels are different.&lt;/p&gt;&#10;&lt;p&gt;Lenia taught us that a neighborhood may cover dozens of cells in every direction. At that scale, direct convolution can become expensive.&lt;/p&gt;&#10;&lt;p&gt;The Fourier transform gives us another route — provided the kernel is centered correctly, which is where the FFT bug this book had to fix lived.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="convolution-becomes-multiplication"&gt;Convolution becomes multiplication&lt;/h2&gt;&#10;&lt;p&gt;For periodic domains:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;convolution in space&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ↕&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;multiplication in frequency&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So instead of sliding a large kernel over every location, we can transform both arrays, multiply them, and transform back.&lt;/p&gt;</description></item><item><title>Build a Reusable Cellular Automata Engine</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/54-chapter/</link><pubDate>Mon, 10 Aug 2026 20:56:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/54-chapter/</guid><description>&lt;p&gt;Across this book we repeatedly rebuilt the same pieces:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;state&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;neighborhood&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rule&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;step loop&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;measurements&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rendering&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That repetition was useful while learning.&lt;/p&gt;&#10;&lt;p&gt;Now it is time to turn those concepts into interfaces.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="keep-the-engine-small"&gt;Keep the engine small&lt;/h2&gt;&#10;&lt;p&gt;A useful engine does not need to know what Conway&amp;rsquo;s Life, Lenia or an NCA is.&lt;/p&gt;&#10;&lt;p&gt;It only needs to orchestrate state transitions.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;from&lt;/span&gt; dataclasses &lt;span style="color:#f92672"&gt;import&lt;/span&gt; dataclass&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;from&lt;/span&gt; typing &lt;span style="color:#f92672"&gt;import&lt;/span&gt; Callable, Any&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@dataclass&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Automaton&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; state: Any&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; step_fn: Callable[[Any], Any]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;step&lt;/span&gt;(self):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;state &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;step_fn(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;state)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;state&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;run&lt;/span&gt;(self, steps):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; _ &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(steps):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;step()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;state&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That is intentionally boring.&lt;/p&gt;</description></item><item><title>Make Experiments Reproducible</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/55-chapter/</link><pubDate>Mon, 10 Aug 2026 20:57:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/55-chapter/</guid><description>&lt;p&gt;By this stage the book contains many systems whose behavior depends on parameters, seeds and implementation choices.&lt;/p&gt;&#10;&lt;p&gt;If we cannot reconstruct a run, we cannot really compare it.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="treat-configuration-as-data"&gt;Treat configuration as data&lt;/h2&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;from&lt;/span&gt; dataclasses &lt;span style="color:#f92672"&gt;import&lt;/span&gt; dataclass, asdict&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@dataclass&lt;/span&gt;(frozen&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ExperimentConfig&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; model: str&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; width: int&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; height: int&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; steps: int&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; seed: int&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; backend: str&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dtype: str&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; params: dict &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then extend with model-specific parameters rather than hiding them in notebook cells.&lt;/p&gt;</description></item><item><title>Run Parameter Sweeps and Benchmarks</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/56-chapter/</link><pubDate>Mon, 10 Aug 2026 20:58:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/56-chapter/</guid><description>&lt;p&gt;Once experiments are reproducible, we can stop treating parameters as one-off choices and start mapping behavior systematically.&lt;/p&gt;&#10;&lt;p&gt;A parameter sweep is not merely a convenience.&lt;/p&gt;&#10;&lt;p&gt;It is a way to turn a model into a measurable landscape.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="build-a-grid-of-experiments"&gt;Build a grid of experiments&lt;/h2&gt;&#10;&lt;p&gt;Sweep over rules and seeds with owned machinery — Chapter 18&amp;rsquo;s runner and Chapter 19&amp;rsquo;s fingerprint, reused exactly:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;from&lt;/span&gt; itertools &lt;span style="color:#f92672"&gt;import&lt;/span&gt; product&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;sweep_rules&lt;/span&gt;(rules, seeds, width&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;201&lt;/span&gt;, generations&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;200&lt;/span&gt;):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; records &lt;span style="color:#f92672"&gt;=&lt;/span&gt; []&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; rule, seed &lt;span style="color:#f92672"&gt;in&lt;/span&gt; product(rules, seeds):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; history &lt;span style="color:#f92672"&gt;=&lt;/span&gt; run_rule(&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; rule,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; width&lt;span style="color:#f92672"&gt;=&lt;/span&gt;width,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; generations&lt;span style="color:#f92672"&gt;=&lt;/span&gt;generations,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; seed&lt;span style="color:#f92672"&gt;=&lt;/span&gt;seed,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; initial&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;random&amp;#34;&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; records&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append({&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;rule&amp;#34;&lt;/span&gt;: rule,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;seed&amp;#34;&lt;/span&gt;: seed,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;**&lt;/span&gt;fingerprint(history),&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; records&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Notice the seed axis.&lt;/p&gt;</description></item><item><title>Generate Figures and Animations</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/57-chapter/</link><pubDate>Mon, 10 Aug 2026 20:59:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/57-chapter/</guid><description>&lt;p&gt;Cellular automata are visual systems.&lt;/p&gt;&#10;&lt;p&gt;That makes figures and animations unusually important.&lt;/p&gt;&#10;&lt;p&gt;But a useful image is not merely a screenshot. It should be a reproducible output of an experiment.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="save-figures-from-data-not-from-memory"&gt;Save figures from data, not from memory&lt;/h2&gt;&#10;&lt;p&gt;Suppose an experiment has produced a spacetime history:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;history &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;stack(states)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A figure generator should accept that result explicitly:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; matplotlib.pyplot &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; plt&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;save_spacetime&lt;/span&gt;(history, path):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; fig, ax &lt;span style="color:#f92672"&gt;=&lt;/span&gt; plt&lt;span style="color:#f92672"&gt;.&lt;/span&gt;subplots(figsize&lt;span style="color:#f92672"&gt;=&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;6&lt;/span&gt;))&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ax&lt;span style="color:#f92672"&gt;.&lt;/span&gt;imshow(history, interpolation&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;nearest&amp;#34;&lt;/span&gt;, aspect&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;auto&amp;#34;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ax&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_xlabel(&lt;span style="color:#e6db74"&gt;&amp;#34;cell&amp;#34;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ax&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_ylabel(&lt;span style="color:#e6db74"&gt;&amp;#34;time&amp;#34;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; fig&lt;span style="color:#f92672"&gt;.&lt;/span&gt;tight_layout()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; fig&lt;span style="color:#f92672"&gt;.&lt;/span&gt;savefig(path, dpi&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;180&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; plt&lt;span style="color:#f92672"&gt;.&lt;/span&gt;close(fig)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;(Verified headless: PNG written with labeled axes from recorded arrays.)&lt;/p&gt;</description></item><item><title>Build a Cellular Automata Laboratory</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/58-chapter/</link><pubDate>Mon, 10 Aug 2026 21:00:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/58-chapter/</guid><description>&lt;p&gt;We now have enough pieces to stop thinking in terms of isolated scripts.&lt;/p&gt;&#10;&lt;p&gt;A useful cellular-automata laboratory should let us define, run, measure, replay and visualize experiments across many kinds of automata without hiding the mechanisms we spent the whole book learning.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="the-laboratory-is-not-the-model"&gt;The laboratory is not the model&lt;/h2&gt;&#10;&lt;p&gt;Keep these concerns separate:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;model definition&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;execution backend&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;experiment configuration&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;metrics&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;artifacts&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;analysis&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A rule should not know where its PNG is saved.&lt;/p&gt;</description></item><item><title>Capstone — Discover, Measure and Explain a New System</title><link>https://aibussin.com/books/cellular-automata-from-first-principles/59-chapter/</link><pubDate>Mon, 10 Aug 2026 21:01:00 +0100</pubDate><guid>https://aibussin.com/books/cellular-automata-from-first-principles/59-chapter/</guid><description>&lt;p&gt;The previous chapter built the laboratory. This one uses it on a single problem.&lt;/p&gt;&#10;&lt;p&gt;The book began with one tiny rule applied to one tiny neighborhood.&lt;/p&gt;&#10;&lt;p&gt;We end with a different question:&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;Can we discover a cellular system, characterize its behavior, test its robustness and explain what we actually know about it?&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;That is the capstone. It uses the ideas rather than listing them: every stage below reuses owned machinery — Lenia configs and kernels (Ch31), discovery scoring (Ch32), outcome classes (Ch33), the measurement stack (Ch18–22), perturbation discipline (Ch35), search strategy (Ch24–25), and experiment records (Ch55).&lt;/p&gt;</description></item></channel></rss>