project-euler/217_balanced_numbers.py

41 lines
974 B
Python
Raw Normal View History

#!/usr/bin/env python3
def next(sums, counts, mod=0):
ln = len(sums) + 9
news = [0] * ln
newc = [0] * ln
for i, (s, c) in enumerate(zip(sums, counts)):
for n in range(10):
news[i + n] += 10 * s + c * n
newc[i + n] += c
return news, newc
left_sums = range(10)
left_count = [0] + [1] * 9
right_sums = range(10)
right_count = [1] * 10
length = 47
mod = 3**15
s = 45
for nofd in range(2, length+1):
partial = sum(l * 10**(nofd//2 + nofd%2) * rc + r * lc
for l, r, lc, rc in
zip(left_sums, right_sums, left_count, right_count))
if not nofd % 2:
s += partial
s %= mod
continue
total = sum(lc * rc
for lc, rc in zip(left_count, right_count))
s += 10 * partial + 45 * 10**(nofd//2) * total
s %= mod
left_sums, left_count = next(left_sums, left_count)
right_sums, right_count = next(right_sums, right_count)
print(s)