Created
September 28, 2019 03:39
-
-
Save routevegetable/0b10d38e490881475fb74c0137408f8d to your computer and use it in GitHub Desktop.
Elementary Cellular Automaton implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <memory.h> | |
void step(char *state, size_t len, char rule) | |
{ | |
/* Buffer large enough to hold all bits */ | |
char state_copy[len]; | |
/* Copy current state */ | |
memcpy(state_copy, state, len); | |
for(size_t i = 0; i < len * 8; i++) | |
{ | |
/* For each bit */ | |
size_t byte_index = i / 8; | |
/* Shift state to match rule */ | |
size_t bit_in_byte = i % 8; | |
/* Center */ | |
char c_byte = state_copy[byte_index]; | |
/* Left */ | |
char l_byte = (byte_index < (len - 1)) ? state_copy[byte_index + 1] : 0; | |
/* Right */ | |
char r_byte = (byte_index > 0) ? state_copy[byte_index - 1] : 0; | |
/* Shift bits into here */ | |
char slice_byte = 0; | |
if(bit_in_byte == 0) | |
{ | |
/* Far right bit */ | |
slice_byte = (c_byte << 1) & 0x7; | |
/* Add top bit from lower byte */ | |
slice_byte |= (r_byte >> 7) & 0x1; | |
} | |
else if(bit_in_byte == 7) | |
{ | |
/* Far left bit */ | |
slice_byte = (c_byte >> 6) & 0x7; | |
/* Add bottom bit from higher byte */ | |
slice_byte |= (l_byte & 0x1) << 2 ; | |
} | |
else | |
{ | |
/* Something in the middle - just shift the byte */ | |
slice_byte = (c_byte >> (bit_in_byte - 1)) & 0x7; | |
} | |
char new_bit = ((rule >> slice_byte) & 0x1) != 0; | |
if(bit_in_byte == 0) state[byte_index] = 0; | |
state[byte_index] |= (new_bit & 0x1) << bit_in_byte; | |
} | |
} | |
void print_state(char *state, size_t len) | |
{ | |
for(size_t i = 0; i < len * 8; i++) | |
{ | |
/* Each bit */ | |
size_t byte_index = i / 8; | |
/* Shift state to match rule */ | |
size_t bit_in_byte = i % 8; | |
if((state[byte_index] >> bit_in_byte) & 0x1) | |
{ | |
printf("O"); | |
} | |
else | |
{ | |
printf("."); | |
} | |
} | |
printf("\n"); | |
} | |
#define STATE_BYTES 20 | |
int main(int argc, char **argv) | |
{ | |
int rule = 30; | |
if(argc > 1) | |
{ | |
rule = atol(argv[1]); | |
} | |
char state[STATE_BYTES]; | |
memset(state, 0, STATE_BYTES); | |
state[0] = 1 << 7; | |
while(1) | |
{ | |
step(state, STATE_BYTES, rule); | |
print_state(state, STATE_BYTES); | |
getchar(); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment