Skip to content

Instantly share code, notes, and snippets.

@odds-get-evened
Last active August 31, 2023 10:00
Show Gist options
  • Save odds-get-evened/eda3566c5fc9316b8c7bfa79194b0f03 to your computer and use it in GitHub Desktop.
Save odds-get-evened/eda3566c5fc9316b8c7bfa79194b0f03 to your computer and use it in GitHub Desktop.
i was bored so i built a machine thing.
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