euler/python/e113.py

53 lines
1.4 KiB
Python
Raw Normal View History

2023-10-02 20:31:46 +02:00
def is_non_bouncy(n: int):
digits = list(map(int, list(str(n))))
decreasing = True
increasing = True
for i in range(len(digits) - 1):
increasing = increasing and digits[i] <= digits[i + 1]
decreasing = decreasing and digits[i] >= digits[i + 1]
return increasing or decreasing
def non_bouncy_below_naiv(digits: int):
threshold = 10 ** digits
non_bouncy = sum([1 for i in range(1, threshold) if is_non_bouncy(i)])
return non_bouncy
def non_bouncy_below(digits: int):
# increasing
s = [1 for _ in range(1, 10)]
result = sum(s)
for _ in range(digits - 1):
s = [sum(s[i:]) for i in range(9)]
result += sum(s) - 9
# The -9 is to avoid double counting 11, 22, 33 for increasing and
# decreasing.
# decreasing
decreasing_count = 0
s = [i + 1 for i in range(1, 10)]
for _ in range(digits - 1):
# print(s)
decreasing_count += sum(s)
s = [sum(s[:i]) + 1 for i in range(1, 10)]
result += decreasing_count
return result
def euler_113():
assert non_bouncy_below_naiv(6) == 12951
assert non_bouncy_below(6) == 12951
assert non_bouncy_below(10) == 277032
assert is_non_bouncy(134468)
assert is_non_bouncy(66420)
assert (not is_non_bouncy(155349))
return non_bouncy_below(100)
if __name__ == "__main__":
solution = euler_113()
print("e113.py: " + str(solution))
assert(solution == 51161058134250)