site-icon

To homepage


Elementary cellular automaton - GPL 2.0

So, this is my first real project uploaded here, so there we go!

A while ago, i watched Daniel's video on "elementary celular automatons" (here), and i wanted to do such thing myself. At the time, i used a raspberry pi 4b as my main computer and i started writing it in python. One of python inherent problems is, that it is incredibly slow. (OK, not that slow, but you get the point) And so i thought i'd do a rewrite in C, because it was one of the few other languees that i was at least somewhat familiar with at the time, and so i did!

However, it now turns out, i cannot find it anywhere, and it looks like the file is corrupted.

So i figured, LET'S DO ANOTHER REWRITE, this time the proper way! Sort of. So i did!

Now, beware, it doesn't have properly sanitized input, but what's the chance of it being used by anyone, let alone in a more serious environment.

I first quiclky threw together something that sort of worked but it was really buggy and soon i decided to ditch the memcpy, because i didn't have any idea how to use it.
Here's how that went:

automaton-v0.c

#include <stdio.h> #include <stdlib.h> #include <string.h> bool isAlive(bool cell_1_state, bool cell_2_state, bool cell_3_state, int rule) { // transformation of the rule to binary form bool rule_binary[8]; for (int i = 0; i < 8; i++) { rule_binary[i] = rule % 2; rule /= 2; } // the actual rule check int count = 0; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) { if (cell_1_state == i && cell_2_state == j && cell_3_state == k) { return(rule_binary[count]); } count ++; } } } } int main() { // size input and handling long long size; printf("Please input an array size (may the number be even, 1 will be added.): "); scanf("%lli", &size); if (size < 0) { printf("Size cannot be negative, quitting.\n"); return(1); } if (size % 2 == 0) { size++; } // rule input and handling int rule; printf("Please input the rule number (0-255, inclusive): "); scanf("%d", &rule); if (rule < 0 || rule > 255) { printf("Invalid rule size, quitting.\n"); return(1); } // steps number input and handling long long steps; printf("Please input the desired number of steps to simulate: "); scanf("%lli", & steps); if (steps <= 0) { printf("Size must be greater than 0, quitting.\n"); return(1); } // dynamic memory allocation and inicialisation of rows of cells bool* row = (bool*)calloc(size * sizeof(bool), sizeof(bool)); bool* row_next = (bool*)malloc(size * sizeof(bool)); if (row == NULL || row_next == NULL) { printf("Memory allocation failed, quitting.\n"); return(-1); } row [size / 2] = 1; // the main loop for (long long step = 0; step < steps; step++) { for (long long i = 0; i < size; i++) { if (row[i]) { printf("#"); } else { printf(" "); } if (i == 0) { row_next[i] = isAlive(row[size-1], row[i], row[i+1], rule); } else if (i == size -1) { row_next[i] = isAlive(row[i-1], row[i], row[0], rule); } else { row_next[i] = isAlive(row[i-1], row[i], row[i+1], rule); } } for (long long i = 0; i < size; i++) { row[i] = row_next[i]; } printf("\n"); } // graceful end free(row); free(row_next); return(0); }

And this worked well enough! It was working and it was one of the least ugly pieces of code i've written so far.

But the problem i had with it, even though it was plenty fast, was that i felt the copying of the values could be done way more efficiently.

And so i did another rewrite, this time based on the previous code:

automaton-v1.c

#include <stdio.h> #include <stdlib.h> #include <string.h> bool isAlive(bool cell_1_state, bool cell_2_state, bool cell_3_state, int rule) { // transformation of the rule to binary form bool rule_binary[8]; for (int i = 0; i < 8; i++) { rule_binary[i] = rule % 2; rule /= 2; } // the actual rule check int count = 0; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) { if (cell_1_state == i && cell_2_state == j && cell_3_state == k) { return(rule_binary[count]); } count ++; } } } } int main() { // input of row size (length) and handling of wrong input long long size; printf("Please input an array size (may the number be even, 1 will be added.): "); scanf("%lli", &size); if (size < 0) { printf("Size cannot be negative, quitting.\n"); return(1); } if (size % 2 == 0) { size++; } // input of role number and handling of wrong input int rule; printf("Please input the rule number (0-255, inclusive): "); scanf("%d", &rule); if (rule < 0 || rule > 255) { printf("Invalid rule size, quitting.\n"); return(1); } // input of number of steps and handling of wrong input long long steps; printf("Please input the desired number of steps to simulate: "); scanf("%lli", & steps); if (steps <= 0) { printf("Size must be greater than 0, quitting.\n"); return(1); } // dynamic memory allocation and inicialisation of rows of cells bool* row = (bool*)calloc(size * sizeof(bool), sizeof(bool)); bool* row_next = (bool*)malloc(size * sizeof(bool)); if (row == NULL || row_next == NULL) { printf("Memory allocation failed, quitting.\n"); return(-1); } row [size / 2] = 1; // the main loop for (long long step = 0; step < steps; step++) { for (long long i = 0; i < size; i++) { if (row[i]) { printf("#"); } else { printf(" "); } if (i == 0) { row_next[i] = isAlive(row[size-1], row[i], row[i+1], rule); } else if (i == size -1) { row_next[i] = isAlive(row[i-1], row[i], row[0], rule); } else { row_next[i] = isAlive(row[i-1], row[i], row[i+1], rule); } } memcpy(row, row_next, size * sizeof(bool)); printf("\n"); } // graceful end free(row); free(row_next); return(0); }

These are very easy to compile - cc automaton-v1.c -o automaton

Also very easy to run - just type ./automaton in terminal.

And in case anyone wanted, i also compiled a static binary for i486 linux here and also a binary for (some?) Windows here, though it needs Microsoft Visual Studio C/C++ to run. Or maybe MinGW, because it was compiled with it? Idk.
You can test it and leave me a message in the guestbook i guess.


Written 22nd of December 2025, last edited 12th of February 2026