Conway's Game of Life: Difference between revisions
Jump to navigation
Jump to search
Line 155: | Line 155: | ||
The grid in the centre is our original grid, and the others give the neighbours above, below, left, right and diagonally. | The grid in the centre is our original grid, and the others give the neighbours above, below, left, right and diagonally. | ||
=== Summing it up === | === Summing it up === | ||
Now we can find out how many neighbours each cell in the original grid has by summing the corresponding elements in each of the 9 grids. For a live cell | Now we can find out how many neighbours each cell in the original grid has by summing ([[Plus]] [[Reduce]]) the corresponding elements in each of the 9 grids. We sum all the grids at once by [[ravel]]ling the [[shape]] <source lang=apl inline>3 3</source> [[matrix]] of grids to obtain a 9-element [[vector]]; otherwise [[Reduce]] would only allow us to sum rows or columns. Here APL's representation of [[Boolean]]s as numbers is advantageous, since otherwise counting the number of true values would require converting them to numbers or using conditional logic. For a live cell the sum is 1 more than the number of neighbours—for example, a 4 in the result means a cell has three neighbours. For a dead cell the result is just the number of neighbours: | ||
<source lang=apl> | <source lang=apl> | ||
Line 175: | Line 175: | ||
This means that all cells which might be live in the next generation will have a sum of 3 (from the first rule) or 3 or 4 (from the second rule). | This means that all cells which might be live in the next generation will have a sum of 3 (from the first rule) or 3 or 4 (from the second rule). | ||
So we're interested in cells with a sum of 3 or 4, | So we're interested in cells with a sum of 3 or 4. We can find these cells with a simple application of [[Equal to]], relying on [[pervasion]] and [[scalar extension]] to distribute the data properly. The result of the last step was a [[scalar]] containing one grid; when paired with the [[vector]] <source lang=apl inline>3 4</source> it is extended to give two grids. Within each grid 3 and 4 are compared with every element by scalar extension again. If the right argument were a flat array rather than being [[enclose]]d, we could obtain a similar, but flat, result using another [[Outer Product]]. | ||
<source lang=apl> | <source lang=apl> | ||
Line 188: | Line 188: | ||
</source> | </source> | ||
The next step is best understood by first considering the two scores 4 and 3 separately | The next step is best understood by first considering the two scores 4 and 3 separately. | ||
(a) A score of 4 corresponds either to a live cell with three neighbours or a dead cell with four neighbours. Only in the former case do we get a cell in the next generation - i.e. we get a cell if the score is 4 ''and'' the cell is currently live. Here we're using APL's [[And]] function, <source lang=apl inline>∧</source> | (a) A score of 4 corresponds either to a live cell with three neighbours or a dead cell with four neighbours. Only in the former case do we get a cell in the next generation - i.e. we get a cell if the score is 4 ''and'' the cell is currently live. Here we're using APL's [[And]] function, <source lang=apl inline>∧</source> | ||
Line 237: | Line 237: | ||
└─────────┘ | └─────────┘ | ||
</source> | </source> | ||
=== Refactoring === | === Refactoring === | ||
But we can take advantage of APL's [[Inner Product]] operator to do the ''and'' operations of each test and then ''or'' the result - the <source lang=apl inline>∨.∧</source> in the following: | But we can take advantage of APL's [[Inner Product]] operator to do the ''and'' operations of each test and then ''or'' the result - the <source lang=apl inline>∨.∧</source> in the following: |