Skip to content

Instantly share code, notes, and snippets.

@schlerp
Created November 2, 2021 05:28
Show Gist options
  • Save schlerp/26de0cffe59253e4f51fb8d15b164033 to your computer and use it in GitHub Desktop.
Save schlerp/26de0cffe59253e4f51fb8d15b164033 to your computer and use it in GitHub Desktop.
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