Created
November 2, 2021 05:28
-
-
Save schlerp/26de0cffe59253e4f51fb8d15b164033 to your computer and use it in GitHub Desktop.
This file contains 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
from typing import Dict, Literal, List, Tuple, Union | |
from itertools import product | |
from random import choice | |
STR_TRUE_VAL = "#" | |
STR_FALSE_VAL = " " | |
def str_repr(val: int): | |
if val: | |
return STR_TRUE_VAL | |
return STR_FALSE_VAL | |
def bin_as_int(bin_num: Union[str, int]): | |
return int(bin_num, 2) | |
def int_as_bin(int_num: int): | |
return format(int_num, "b") | |
def int_as_str(int_num: int, width: int = 8): | |
return str(int_as_bin(int_num)).replace("0b", "").rjust(width, "0") | |
AutomataKey1D = Literal[0b111, 0b110, 0b101, 0b100, 0b011, 0b010, 0b001, 0b000] | |
AutomataValue1D = Literal[0b0, 0b1] | |
AutomataRule1D = Dict[AutomataKey1D, AutomataValue1D] | |
AutomataPattern1D = List[AutomataValue1D] | |
automata_keys_ordered = [0b111, 0b110, 0b101, 0b100, 0b011, 0b010, 0b001, 0b000] | |
automata_rule_184: AutomataRule1D = { | |
0b111: 1, | |
0b110: 0, | |
0b101: 1, | |
0b100: 1, | |
0b011: 1, | |
0b010: 0, | |
0b001: 0, | |
0b000: 0, | |
} | |
def build_automata_rule(wolfram_code: int): | |
return { | |
x: int(y) | |
for x, y in zip( | |
automata_keys_ordered, [char for char in int_as_str(wolfram_code, 8)] | |
) | |
} | |
class Automata: | |
pass | |
class Automata1D(Automata): | |
def __init__( | |
self, | |
rule: AutomataRule1D, | |
seq_len: int = 25, | |
start_pattern: AutomataPattern1D = None, | |
outside_values: Tuple[AutomataValue1D, AutomataValue1D] = (0b1, 0b0), | |
): | |
self.rule = rule | |
self.seq_len = seq_len | |
self.start_pattern = ( | |
start_pattern | |
if start_pattern | |
else [choice([0b1, 0b0]) for _ in range(seq_len)] | |
) | |
self.outside_values = outside_values | |
def _next_state(self, current_state: AutomataPattern1D): | |
next_state = [None for _ in range(len(current_state))] | |
for idx, mid_val in enumerate(current_state): | |
left_val, right_val = None, None | |
left_val = current_state[idx - 1] if idx > 0 else self.outside_values[0] | |
right_val = ( | |
current_state[idx + 1] | |
if idx < len(current_state) - 1 | |
else self.outside_values[-1] | |
) | |
neighbourhood_key = bin_as_int("".join([left_val, mid_val, right_val])) | |
next_state[idx] = self.rule[neighbourhood_key] | |
return next_state | |
def run(self, n_iterations: int = 25): | |
current_state = self.start_pattern | |
for i in range(n_iterations): | |
print("".join([str_repr(x) for x in current_state])) | |
current_state = self._next_state(current_state) | |
print("".join([str_repr(x) for x in current_state])) | |
if __name__ == "__main__": | |
print(automata_rule_184) | |
print(build_automata_rule(184)) | |
ca = Automata1D(automata_rule_184, seq_len=250) | |
ca.run(n_iterations=512) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment