1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- from fractions import Fraction as F
- from collections import defaultdict
- from itertools import product
- from math import factorial
- class NematodeNumber:
- P = F(1, 2)
- def __init__(self, n):
- if isinstance(n, int):
- self._val = defaultdict(lambda: F(0))
- self._val[n] = F(1)
- else:
- self._val = n
- @classmethod
- def _breed(cls, n):
- def binom(n, k):
- n_choose_k = factorial(n) // (factorial(k) * factorial(n - k))
- return n_choose_k * cls.P**k * (1 - cls.P)**(n - k)
- leftover, pairs = n % 2, n // 2
- result = defaultdict(lambda: F(0))
- for n_bab in range(pairs + 1):
- prob = binom(pairs, n_bab)
- result[pairs*2 + n_bab + leftover] = prob
- return result
- def __add__(self, other):
- left = self._val
- right = other._val
- result = defaultdict(lambda: F(0))
- for (l, lp), (r, rp) in product(left.items(), right.items()):
- for b, bp in self._breed(l+r).items():
- result[b] += lp*rp*bp
- return NematodeNumber(result)
- def __pow__(self, exponent):
- base = self._val
- for _ in range(exponent):
- next_ = defaultdict(lambda: F(0))
- for n, np in base.items():
- for b, bp in self._breed(n).items():
- next_[b] += np*bp
- base = next_
- return NematodeNumber(base)
- def __repr__(self):
- return repr(self._val)
- def expectation_value(self):
- return sum(val*prob for (val, prob) in self._val.items())
- def limit():
- one = NematodeNumber(1)
- base_result = one + one
- for i in range(1, 30):
- res = base_result ** i
- print(f"{i: 3}: {res.expectation_value()}")
- """
- 1: 3.0
- 2: 3.625
- 3: 4.40625
- 4: 5.3828125 -> 5 49/128
- 5: 6.603515625
- 6: 8.12939453125
- 7: 10.0367431640625
- 8: 12.420928955078125
- 9: 15.401161193847656
- 10: 19.12645149230957
- 11: 23.783064365386963
- 12: 29.603830456733704
- 13: 36.87978807091713
- 14: 45.97473508864641
- 15: 57.343418860808015
- 16: 71.55427357601002
- 17: 89.31784197001252
- """
- def main():
- # r1 = add({2: F(1)}, {2: F(1)})
- # print(r1)
- # r2 = add(r1, r1)
- # print(r2)
- # print(exp({2: F(1)}, 2))
- # val = exp(add({1: F(1)}, {1: F(1)}), 4)
- limit()
- # print(float(expectation_value(val)))
- if __name__ == "__main__":
- main()
|