Last active
August 31, 2023 10:00
-
-
Save odds-get-evened/eda3566c5fc9316b8c7bfa79194b0f03 to your computer and use it in GitHub Desktop.
i was bored so i built a machine thing.
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
import asyncio | |
import random | |
import sys | |
import time | |
""" | |
i was bored and couldn't come up with a concept to work on | |
so i made this pseudo-machine. =) | |
""" | |
def bound_int(n: int, minv: int, maxv: int) -> int: | |
""" | |
always returns an integer value between the min/max | |
given any integer | |
:param n: any given number | |
:param minv: lower bounds | |
:param maxv: upper bounds | |
:return: number between the min/max values | |
""" | |
return ((n - minv) % (maxv - minv + 1)) + minv | |
class Heartbeat: | |
INSTRUCTIONS: list[str] = ["<", ">", "|", "^"] | |
STATUS: list[str] = ["a", "b", "0", "1", "#"] | |
WEIGHTS: list[float] = [0.8, 0.6, 0.8, 0.6, 0.1] | |
def __init__(self, tape_len=8, exit_state=True): | |
random.seed(time.time()) | |
self.tape = [ | |
random.choices(population=self.STATUS, weights=self.WEIGHTS)[0] | |
for _ | |
in range(tape_len) | |
] | |
self.posi_index: int = 0 | |
self.exit_state: bool = exit_state | |
self._loop = asyncio.get_event_loop() | |
try: | |
self._loop.run_until_complete(self.start()) | |
except KeyboardInterrupt: | |
self._loop.stop() | |
self._loop.close() | |
async def start(self) -> None: | |
""" | |
let's get started | |
""" | |
while True: | |
stat: str = self.tape[self.posi_index] | |
instr: str = random.choices(self.INSTRUCTIONS, [0.7, 0.8, 0.5, 0.2])[0] | |
print(f"@ {self.posi_index} instr.: {stat}{instr}\t\ttape: {self.tape}") | |
self.proc((stat, instr)) | |
await asyncio.sleep(1) | |
def proc(self, instr_set: tuple) -> None: | |
""" | |
process the state and instruction for the current cell | |
:param instr_set: a tuple pair containing state, and instruction | |
""" | |
cur_state: str = instr_set[0] | |
cur_action: str = instr_set[1] | |
# handle state function | |
self.handle_state(cur_state) | |
self.handle_action(cur_action) | |
def handle_state(self, state: str) -> None: | |
""" | |
how the machine handles states (right now this is arbitrary, | |
and at some point would like this to handle string formulae | |
:param state: | |
""" | |
if state in 'a b'.split(): | |
self.tape[self.posi_index] = 'a' if self.tape[self.posi_index] == 'b' else 'b' | |
if state == '0': | |
pass | |
if state == '1': | |
self.tape[self.posi_index] = random.choices(population=self.STATUS, weights=self.WEIGHTS)[0] | |
if state == '#': | |
if self.exit_state: | |
print(f"all done. {self.tape}") | |
sys.exit(0) | |
else: | |
time.sleep(5.0) | |
def handle_action(self, action: str) -> None: | |
""" | |
how the machine will transition after processing | |
current cell's state value | |
:param action: | |
""" | |
if action in '< >'.split(): | |
if action == '<': | |
self.posi_index -= 2 # go back 1 step (1 + current step) | |
if action == '>': | |
pass # advance 1 step | |
if action == '|': | |
self.posi_index -= 1 # pause on current cell | |
if action == '^': | |
pass # restart or advance 1 step | |
''' always be advancing 1 step ''' | |
self.posi_index = bound_int(self.posi_index+1, 0, len(self.tape)-1) | |
def do_heartbeat(): | |
Heartbeat(exit_state=False, tape_len=16) | |
def main(): | |
do_heartbeat() | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment