53 lines
1.4 KiB
Python
53 lines
1.4 KiB
Python
|
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)
|
||
|
|