Skip to content

Created problem_112.py in project_euler #2532

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Oct 3, 2020
Empty file.
89 changes: 89 additions & 0 deletions project_euler/problem_112/sol1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
"""
Problem 112: https://projecteuler.net/problem=112

Working from left-to-right if no digit is exceeded by the digit to its left it is
called an increasing number; for example, 134468.
Similarly if no digit is exceeded by the digit to its right it is called a decreasing
number; for example, 66420.
We shall call a positive integer that is neither increasing nor decreasing a "bouncy"
number, for example, 155349.
Clearly there cannot be any bouncy numbers below one-hundred, but just over half of
the numbers below one-thousand (525) are bouncy. In fact, the least number for which
the proportion of bouncy numbers first reaches 50% is 538.
Surprisingly, bouncy numbers become more and more common and by the time we reach
21780 the proportion of bouncy numbers is equal to 90%.

Find the least number for which the proportion of bouncy numbers is exactly 99%.
"""


def check_bouncy(n: int) -> bool:
"""
Returns True if number is bouncy, False otherwise
>>> check_bouncy(6789)
False
>>> check_bouncy(-12345)
False
>>> check_bouncy(0)
False
>>> check_bouncy(6.74)
Traceback (most recent call last):
...
ValueError: check_bouncy() accepts only integer arguments
>>> check_bouncy(132475)
True
>>> check_bouncy(34)
False
>>> check_bouncy(341)
True
>>> check_bouncy(47)
False
>>> check_bouncy(-12.54)
Traceback (most recent call last):
...
ValueError: check_bouncy() accepts only integer arguments
>>> check_bouncy(-6548)
True
"""
if not isinstance(n, int):
raise ValueError("check_bouncy() accepts only integer arguments")
return "".join(sorted(str(n))) != str(n) and "".join(sorted(str(n)))[::-1] != str(n)


def solution(percent: float = 99) -> int:
"""
Returns the least number for which the proportion of bouncy numbers is
exactly 'percent'
>>> solution(50)
538
>>> solution(90)
21780
>>> solution(80)
4770
>>> solution(105)
Traceback (most recent call last):
...
ValueError: solution() only accepts values from 0 to 100
>>> solution(100.011)
Traceback (most recent call last):
...
ValueError: solution() only accepts values from 0 to 100
"""
if not 0 < percent < 100:
raise ValueError("solution() only accepts values from 0 to 100")
bouncy_num = 0
num = 1

while True:
if check_bouncy(num):
bouncy_num += 1
if (bouncy_num / num) * 100 >= percent:
return num
num += 1


if __name__ == "__main__":
from doctest import testmod

testmod()
print(f"{solution(99)}")