main.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. from fractions import Fraction as F
  2. from collections import defaultdict
  3. from itertools import product
  4. from math import factorial
  5. class NematodeNumber:
  6. P = F(1, 2)
  7. def __init__(self, n):
  8. if isinstance(n, int):
  9. self._val = defaultdict(lambda: F(0))
  10. self._val[n] = F(1)
  11. else:
  12. self._val = n
  13. @classmethod
  14. def _breed(cls, n):
  15. def binom(n, k):
  16. n_choose_k = factorial(n) // (factorial(k) * factorial(n - k))
  17. return n_choose_k * cls.P**k * (1 - cls.P)**(n - k)
  18. leftover, pairs = n % 2, n // 2
  19. result = defaultdict(lambda: F(0))
  20. for n_bab in range(pairs + 1):
  21. prob = binom(pairs, n_bab)
  22. result[pairs*2 + n_bab + leftover] = prob
  23. return result
  24. def __add__(self, other):
  25. left = self._val
  26. right = other._val
  27. result = defaultdict(lambda: F(0))
  28. for (l, lp), (r, rp) in product(left.items(), right.items()):
  29. for b, bp in self._breed(l+r).items():
  30. result[b] += lp*rp*bp
  31. return NematodeNumber(result)
  32. def __pow__(self, exponent):
  33. base = self._val
  34. for _ in range(exponent):
  35. next_ = defaultdict(lambda: F(0))
  36. for n, np in base.items():
  37. for b, bp in self._breed(n).items():
  38. next_[b] += np*bp
  39. base = next_
  40. return NematodeNumber(base)
  41. def __repr__(self):
  42. return repr(self._val)
  43. def expectation_value(self):
  44. return sum(val*prob for (val, prob) in self._val.items())
  45. def limit():
  46. one = NematodeNumber(1)
  47. base_result = one + one
  48. for i in range(1, 30):
  49. res = base_result ** i
  50. print(f"{i: 3}: {res.expectation_value()}")
  51. """
  52. 1: 3.0
  53. 2: 3.625
  54. 3: 4.40625
  55. 4: 5.3828125 -> 5 49/128
  56. 5: 6.603515625
  57. 6: 8.12939453125
  58. 7: 10.0367431640625
  59. 8: 12.420928955078125
  60. 9: 15.401161193847656
  61. 10: 19.12645149230957
  62. 11: 23.783064365386963
  63. 12: 29.603830456733704
  64. 13: 36.87978807091713
  65. 14: 45.97473508864641
  66. 15: 57.343418860808015
  67. 16: 71.55427357601002
  68. 17: 89.31784197001252
  69. """
  70. def main():
  71. # r1 = add({2: F(1)}, {2: F(1)})
  72. # print(r1)
  73. # r2 = add(r1, r1)
  74. # print(r2)
  75. # print(exp({2: F(1)}, 2))
  76. # val = exp(add({1: F(1)}, {1: F(1)}), 4)
  77. limit()
  78. # print(float(expectation_value(val)))
  79. if __name__ == "__main__":
  80. main()