How to resolve the algorithm Elementary cellular automaton step by step in the C++ programming language

Published on 7 June 2024 03:52 AM

How to resolve the algorithm Elementary cellular automaton step by step in the C++ programming language

Table of Contents

Problem Statement

An elementary cellular automaton is a one-dimensional cellular automaton where there are two possible states (labeled 0 and 1) and the rule to determine the state of a cell in the next generation depends only on the current state of the cell and its two immediate neighbors. Those three values can be encoded with three bits. The rules of evolution are then encoded with eight bits indicating the outcome of each of the eight possibilities 111, 110, 101, 100, 011, 010, 001 and 000 in this order. Thus for instance the rule 13 means that a state is updated to 1 only in the cases 011, 010 and 000, since 13 in binary is 0b00001101.

Create a subroutine, program or function that allows to create and visualize the evolution of any of the 256 possible elementary cellular automaton of arbitrary space length and for any given initial state. You can demonstrate your solution with any automaton of your choice. The space state should wrap: this means that the left-most cell should be considered as the right neighbor of the right-most cell, and reciprocally. This task is basically a generalization of one-dimensional cellular automata.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Elementary cellular automaton step by step in the C++ programming language

This C++ program simulates the evolution of a one-dimensional cellular automaton according to a specific rule (rule 30 in this case).

cellular automaton is a system composed of a grid of cells, each of which can be in one of several states. The states of the cells evolve over time based on a set of rules that depend on the states of the neighboring cells.

Rule 30 is a specific rule for cellular automata, which specifies the new state of a cell based on the states of its two neighbors. In this case, the rule is implemented by the RULE_TEST macro, which takes a bitmask representing the states of the three cells (the current cell and its two neighbors) and returns 1 if the new state should be 1, and 0 otherwise.

The program begins by initializing a bitset, called state, to represent the initial state of the cellular automaton. The bitset is initialized with a single 1 bit in the middle, representing a single "on" cell.

The evolve function, takes the current state of the cellular automaton, represented by the bitset state, and updates it based on the specified rule. The function iterates over each cell in the bitset, and for each cell, it calculates the new state of the cell based on the states of its two neighbors. The new state is stored in a temporary bitset called t, and then the original bitset state is updated with the new values from t.

The show function is used to print the current state of the cellular automaton to the console. It iterates over the bitset state and prints a '#' character for each 1 bit (representing an "on" cell) and a ' ' character for each 0 bit (representing an "off" cell).

The main function sets up the initial state of the cellular automaton and then calls the evolve function 10 times to simulate 10 generations of evolution. After each generation, the show function is called to print the current state of the cellular automaton to the console.

The output of the program will show the evolution of the cellular automaton over time, based on rule 30. The initial state is a single "on" cell in the middle of the bitset. As the cellular automaton evolves, the "on" cells spread out and form patterns that eventually fill the entire bitset.

Source code in the cpp programming language

#include <bitset>
#include <stdio.h>

#define SIZE	           80
#define RULE               30
#define RULE_TEST(x)       (RULE & 1 << (7 & (x)))

void evolve(std::bitset<SIZE> &s) {
    int i;
    std::bitset<SIZE> t(0);
    t[SIZE-1] = RULE_TEST( s[0] << 2 | s[SIZE-1] << 1 | s[SIZE-2] );
    t[     0] = RULE_TEST( s[1] << 2 | s[     0] << 1 | s[SIZE-1] );
    for (i = 1; i < SIZE-1; i++)
	t[i] = RULE_TEST( s[i+1] << 2 | s[i] << 1 | s[i-1] );
    for (i = 0; i < SIZE; i++) s[i] = t[i];
}
void show(std::bitset<SIZE> s) {
    int i;
    for (i = SIZE; --i; ) printf("%c", s[i] ? '#' : ' ');
    printf("\n");
}
int main() {
    int i;
    std::bitset<SIZE> state(1);
    state <<= SIZE / 2;
    for (i=0; i<10; i++) {
	show(state);
	evolve(state);
    }
    return 0;
}


  

You may also check:How to resolve the algorithm Speech synthesis step by step in the FutureBasic programming language
You may also check:How to resolve the algorithm Sorting algorithms/Radix sort step by step in the Scheme programming language
You may also check:How to resolve the algorithm Haversine formula step by step in the Euler Math Toolbox programming language
You may also check:How to resolve the algorithm Averages/Median step by step in the Octave programming language
You may also check:How to resolve the algorithm Minimal steps down to 1 step by step in the Java programming language