from math import floor
from collections import deque
from typing import Dict, Generator


def padovan_r() -> Generator[int, None, None]:
    last = deque([1, 1, 1], 4)
    while True:
        last.append(last[-2] + last[-3])
        yield last.popleft()

_p, _s = 1.324717957244746025960908854, 1.0453567932525329623

def padovan_f(n: int) -> int:
    return floor(_p**(n-1) / _s + .5)

def padovan_l(start: str='A',
             rules: Dict[str, str]=dict(A='B', B='C', C='AB')
             ) -> Generator[str, None, None]:
    axiom = start
    while True:
        yield axiom
        axiom = ''.join(rules[ch] for ch in axiom)


if __name__ == :
    from itertools import islice

    print()
    print(str([padovan_f(n) for n in range(20)])[1:-1])

    r_generator = padovan_r()
    if all(next(r_generator) == padovan_f(n) for n in range(64)):
        print()
    else:
        print()

    print()
    l_generator = padovan_l(start='A', rules=dict(A='B', B='C', C='AB'))
    print('\n'.join(f
                    for string in islice(l_generator, 10)))

    r_generator = padovan_r()
    l_generator = padovan_l(start='A', rules=dict(A='B', B='C', C='AB'))
    if all(len(next(l_generator)) == padovan_f(n) == next(r_generator)
           for n in range(32)):
        print()
    else:
        print()