k98kurz icon

rule110.py

k98kurz | PRO | 09/05/21 05:34:01 PM UTC (Edited) | 0 ⭐ | 723 👁️ | Never ⏰ | []
Python |

3 KB

|

None

|

0 👍

/

0 👎

from secrets import token_bytes
from sys import argv
from time import sleep
 
 
rules = {
    '111': '0',
    '110': '1',
    '101': '1',
    '100': '0',
    '011': '1',
    '010': '1',
    '001': '1',
    '000': '0',
}
 
 
def prettify(tape: str) -> str:
    return tape.replace('0', ' ').replace('1', '.')
 
 
def next_generation(tape: str) -> str:
    tape = tape
    new_tape = rules[tape[-1:] + tape[:2]]
    for i in range(0, len(tape) - 2):
        code = tape[i:i+3]
        new_tape += rules[code]
    new_tape += rules[tape[-2:] + tape[0]]
    return new_tape
 
 
def simulate(tape: str, number_of_generations: int, delay: int, use_pretty: bool = False):
    if number_of_generations == 0:
        number_of_generations = -1
    while number_of_generations != 0:
        print(prettify(tape) if use_pretty else tape)
        sleep(delay/1000)
        tape = next_generation(tape)
        number_of_generations -= 1
 
 
def setup_tape(tape_len: int, starting_string: str) -> str:
    string = ''
    if starting_string != '':
        while len(string) < tape_len:
            string += starting_string
    else:
        while len(string) < tape_len:
            string += "{0:b}".format(int.from_bytes(token_bytes(), 'little'))
    return string[:tape_len]
 
 
def interactive():
    val = 20
    prevval = val
    while val != 0:
        print(f'example tape_len={val}')
        print(setup_tape(int(val), ''))
        prevval = val
        val = input('next int len to try (or non-int to stop): ')
        try:
            val = int(val)
        except:
            val = 0
 
    tape = setup_tape(prevval, '')
    simulate(tape, 0, 42, True)
 
 
def usage(script):
    print(f'usage: python {script} [tape_len|interactive|i] [number_of_generations] [delay in ms] [prettify] [starting_string]')
    print('\ttape_len is the integer number of elements in the tape')
    print('\fif interactive or i is chosen, interactively determine the best length')
    print('\tif number_of_generations is omitted or is 0, the simulation will continue until interrupted')
    print('\tif delay is omitted or is 0, a 42ms delay is used as default')
    print('\tif prettify is set to 1, the prettifier will be used')
    print('\tif starting_string has len less than tape_len, it will be repeated to fill out the rest')
 
 
def main(args):
    if len(args) == 1 or args[1] in ('h', '?', '-h', '-?', '--help'):
        usage(args[0])
        exit()
 
    starting_string = args[5] if len(args) == 6 else ''
    use_pretty = (args[4] in ('1', 'True', 'true')) if len(args) >= 5 else False
    delay = int(args[3]) if len(args) >= 4 else 42
    delay = delay if delay > 0 else 42
    number_of_generations = int(args[2]) if len(args) >= 3 else 0
 
    if args[1] in ('interactive', 'i'):
        return interactive()
 
    tape_len = int(args[1])
 
    tape = setup_tape(tape_len, starting_string)
    simulate(tape, number_of_generations, delay, use_pretty)
 
 
if __name__ == '__main__':
    main(argv)
 

Comments