Processing Life cell lists as streams in Unix
Posted: August 24th, 2020, 12:15 pm
This is a pretty simple idea and I'm sure I'm not the first (actually I have done things like this before, but using a stream wasn't the point).
This can process a list of cells, such as these for a glider:
It then outputs the next generation.
My code looks a bit obfuscated, but it works by taking each cell (i, j) and fanning out two copies of each neighboring cell as well as a single copy of the cells themselves. When you count unique cell coordinates, the cell value is encoded as the odd/even bit (count mod 2) while the number of neighbors is on the higher bits (count div 2). You sort them and count with uniq and filter based on the count.
I didn't work hard to make this very concise. Maybe someone has something better.
More importantly, I would like to avoid the sort step. If you start with the cells in sorted order, you get "mostly" sorted after the fanout step. If you could maintain 3 pointers into the stream, you could do the count without sorting again. Is there a way to do this with unix commands without sort? (Maybe by using tee)
Code: Select all
awk '{for (i = -1; i <= 1; i++)
for (j = -1; j <= 1; j++) {
if (i != 0 || j != 0) print $1 + i, $2 + j
print $1 + i, $2 + j
}}' | sort | uniq -c | awk '{if ($1 >=5 && $1 <= 7) print $2, $3}'Code: Select all
0 0
0 2
1 1
1 2
2 1
Code: Select all
0 2
1 0
1 2
2 1
2 2I didn't work hard to make this very concise. Maybe someone has something better.
More importantly, I would like to avoid the sort step. If you start with the cells in sorted order, you get "mostly" sorted after the fanout step. If you could maintain 3 pointers into the stream, you could do the count without sorting again. Is there a way to do this with unix commands without sort? (Maybe by using tee)