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__ == "__main__": from itertools import islice print("The first twenty terms of the sequence.") 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("\nThe recurrence and floor based algorithms match to n=63 .") else: print("\nThe recurrence and floor based algorithms DIFFER!") print("\nThe first 10 L-system string-lengths and strings") l_generator = padovan_l(start='A', rules=dict(A='B', B='C', C='AB')) print('\n'.join(f" {len(string):3} {repr(string)}" 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("\nThe L-system, recurrence and floor based algorithms match to n=31 .") else: print("\nThe L-system, recurrence and floor based algorithms DIFFER!")