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

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Elementary cellular automaton step by step in the Ceylon 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 Ceylon programming language

Source code in the ceylon programming language

class Rule(number) satisfies Correspondence {
	
	shared Byte number;
	
	"all 3 bit patterns will return a value so this is always true"
	shared actual Boolean defines(Boolean[3] key) => true;
	
	shared actual Boolean? get(Boolean[3] key) => 
			number.get((key[0] then 4 else 0) + (key[1] then 2 else 0) + (key[2] then 1 else 0));
	
	function binaryString(Integer integer, Integer maxPadding) =>
			Integer.format(integer, 2).padLeading(maxPadding, '0');
	
	string => 
			let (digits = binaryString(number.unsigned, 8))
			"Rule #``number``
			 ``" | ".join { for (pattern in $111..0) binaryString(pattern, 3) }`` 
			 ``" | ".join(digits.map((Character element) => element.string.pad(3)))``";
}

class ElementaryAutomaton {
	
	shared static ElementaryAutomaton|ParseException parse(Rule rule, String cells, Character aliveChar, Character deadChar) {
		if (!cells.every((Character element) => element == aliveChar || element == deadChar)) {
			return ParseException("the string was not a valid automaton");
		}
		return ElementaryAutomaton(rule, cells.map((Character element) => element == aliveChar));
	}

	shared Rule rule;
	
	Array cells;
	
	shared new(Rule rule, {Boolean*} initialCells) {
		this.rule = rule;
		this.cells = Array { *initialCells }; 
	}
	
	shared Boolean evolve() {
		
		if (cells.empty) {
			return false;
		}
		
		function left(Integer index) {
			assert (exists cell = cells[index - 1] else cells.last);
			return cell;
		}

		function right(Integer index) {
			assert (exists cell = cells[index + 1] else cells.first);
			return cell;
		}
		
		value newCells = Array.ofSize(cells.size, false);
		for (index->cell in cells.indexed) {
			value neighbourhood = [left(index), cell, right(index)];
			assert (exists newCell = rule[neighbourhood]);
			newCells[index] = newCell;
		}

		if (newCells == cells) {
			return false;
		}
		
		newCells.copyTo(cells);
		return true;	
	}
	
	shared void display(Character aliveChar = '#', Character deadChar = ' ') {
		print("".join(cells.map((Boolean element) => element then aliveChar else deadChar)));
	}
}

shared void run() {
	value rule = Rule(90.byte);
	print(rule);
	
	value automaton = ElementaryAutomaton.parse(rule, "          #          ", '#', ' ');
	assert (is ElementaryAutomaton automaton);
	
	for (generation in 0..10) {
		automaton.display();
		automaton.evolve();
	}
}


  

You may also check:How to resolve the algorithm Loops/Continue step by step in the Lasso programming language
You may also check:How to resolve the algorithm Kronecker product based fractals step by step in the Rust programming language
You may also check:How to resolve the algorithm Total circles area step by step in the Phix programming language
You may also check:How to resolve the algorithm Hailstone sequence step by step in the Oz programming language
You may also check:How to resolve the algorithm Walk a directory/Non-recursively step by step in the Python programming language