# волшебная троица
def cons(x, y): return (x,y)
def car(l): return l[0]
def cdr(l): return l[1]

# объект-обертка для мемоизированных ленивых вычислений
class Lazy:
  def __init__(self, expr):
    self.expression = expr
    self.calculated = False
    self.rezult = False
  
  def getvalue(self):
    if not self.calculated:
      self.rezult = self.expression()
      self.calculated = True
    return self.rezult

# хвост потока
def stail(s): return cdr(s).getvalue()

# потоковые аналоги списковых функций

def stake(n, l):
  r = []
  while n>0:
    r.append(car(l))
    l = stail(l)
    n = n-1
  return r

def sfilter(f, s):
  if f(car(s)):
    return cons(car(s), Lazy(lambda: sfilter(f, stail(s))))
  else:
    return sfilter(f, stail(s))

# тестовые примеры

def thru2from(n): return cons(n, Lazy(lambda: thru2from(n+2)))

n = 5000

print("первые {} простых чисел через гипотезу Бертрана:".format(n))
primesBert = cons(2, Lazy(lambda: sfilter(isprime, thru2from(3))))
def isprime(n):
    l = primesBert
    while car(l)*car(l) <= n:
      if n % car(l) == 0: return False
      l = stail(l)
    return True
print(stake(n, primesBert))