Skip to content

Instantly share code, notes, and snippets.

@itarato
Last active February 19, 2025 12:31
Show Gist options
  • Save itarato/1eda923c5c14224bffdd452b7ad1fa71 to your computer and use it in GitHub Desktop.
Save itarato/1eda923c5c14224bffdd452b7ad1fa71 to your computer and use it in GitHub Desktop.
Monster fibonacci with generators
from __future__ import annotations
class GeneratorWithHistory:
def __init__(self, generator) -> None:
self.generator = generator
self.memory = []
self.index = 0
def next(self, needed_index: int):
while self.index <= needed_index:
self.memory.append(self.generator.__next__())
self.index += 1
return self.memory[needed_index]
class IndexedGeneratorCaller:
def __init__(self, generator_with_history: GeneratorWithHistory, index: int = 0):
self.generator_with_history = generator_with_history
self.index = index
def next(self):
value = self.generator_with_history.next(self.index)
self.index += 1
return value
class GeneratorRegister:
__instance = None
def instance() -> GeneratorRegister:
if not GeneratorRegister.__instance:
GeneratorRegister.__instance = GeneratorRegister()
return GeneratorRegister.__instance
def __init__(self):
self.registry = {}
def register(self, fn):
self.registry[fn] = GeneratorWithHistory(fn())
def get(self, fn) -> GeneratorWithHistory:
return self.registry[fn]
def fib():
yield 0
yield 1
lhs = IndexedGeneratorCaller(GeneratorRegister.instance().get(fib))
rhs = IndexedGeneratorCaller(GeneratorRegister.instance().get(fib), 1)
while True:
yield (lhs.next() + rhs.next())
GeneratorRegister.instance().register(fib)
fib_gen = IndexedGeneratorCaller(GeneratorRegister.instance().get(fib))
for _ in range(0, 10):
print(fib_gen.next())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment