✨ 新增欧拉第33题“数字约分分数”双解法实现
This commit is contained in:
94
solutions/0033.DigitCancelling/euler_33.py
Normal file
94
solutions/0033.DigitCancelling/euler_33.py
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
"""
|
||||||
|
The fraction 49/98 is a curious fraction,
|
||||||
|
as an inexperienced mathematician in attempting to simplify it may incorrectly believe
|
||||||
|
that 49/98 = 4/8 , which is correct, is obtained by cancelling the 9s.
|
||||||
|
|
||||||
|
We shall consider fractions like, 30/50=3/5 , to be trivial examples.
|
||||||
|
|
||||||
|
There are exactly four non-trivial examples of this type of fraction,
|
||||||
|
less than one in value, and containing two digits in the numerator and denominator.
|
||||||
|
|
||||||
|
If the product of these four fractions is given in its lowest common terms,
|
||||||
|
find the value of the denominator.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import time
|
||||||
|
from functools import reduce
|
||||||
|
from math import gcd
|
||||||
|
|
||||||
|
|
||||||
|
def timer(func):
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
start_time = time.time()
|
||||||
|
result = func(*args, **kwargs)
|
||||||
|
end_time = time.time()
|
||||||
|
print(f"{func.__name__} taken: {end_time - start_time:.6f} seconds")
|
||||||
|
return result
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
@timer
|
||||||
|
def main() -> None:
|
||||||
|
res = list()
|
||||||
|
for numerator in range(12, 100):
|
||||||
|
for denominator in range(numerator * 2, 100):
|
||||||
|
if numerator % 10 == 0 and denominator % 10 == 0:
|
||||||
|
continue
|
||||||
|
all_nums = set(
|
||||||
|
[numerator // 10, numerator % 10, denominator // 10, denominator % 10]
|
||||||
|
)
|
||||||
|
if len(all_nums) == 3:
|
||||||
|
a = [i for i in str(numerator) if i not in str(denominator)][0]
|
||||||
|
b = [i for i in str(denominator) if i not in str(numerator)][0]
|
||||||
|
if a != "0" and b != "0":
|
||||||
|
if (int(a) / int(b)) == (numerator / denominator):
|
||||||
|
print(f"{numerator}/{denominator}")
|
||||||
|
res.append((numerator, denominator))
|
||||||
|
res = reduce(lambda x, y: (x[0] * y[0], x[1] * y[1]), res)
|
||||||
|
res = res[1] // gcd(res[0], res[1])
|
||||||
|
print(f"Answer: {res}")
|
||||||
|
|
||||||
|
|
||||||
|
@timer
|
||||||
|
def main_two() -> None:
|
||||||
|
results = []
|
||||||
|
|
||||||
|
for numerator in range(11, 100):
|
||||||
|
for denominator in range(numerator + 1, 100): # 分母必须大于分子
|
||||||
|
# 检查是否构成非平凡的情况(有共同数字但不是都为0)
|
||||||
|
num_str, den_str = str(numerator), str(denominator)
|
||||||
|
common_digits = set(num_str) & set(den_str)
|
||||||
|
|
||||||
|
# 排除平凡情况和没有共同数字的情况
|
||||||
|
if len(common_digits) != 1 or "0" in common_digits:
|
||||||
|
continue
|
||||||
|
|
||||||
|
common_digit = list(common_digits)[0]
|
||||||
|
|
||||||
|
# 构造约分后的分数
|
||||||
|
simplified_num = int(num_str.replace(common_digit, "", 1))
|
||||||
|
simplified_den = int(den_str.replace(common_digit, "", 1))
|
||||||
|
|
||||||
|
# 避免除以0
|
||||||
|
if simplified_den == 0:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 检查分数是否相等
|
||||||
|
if numerator * simplified_den == denominator * simplified_num:
|
||||||
|
print(f"{numerator}/{denominator} = {simplified_num}/{simplified_den}")
|
||||||
|
results.append((numerator, denominator))
|
||||||
|
|
||||||
|
# 计算最终结果(所有分数乘积的分母)
|
||||||
|
product_num = reduce(lambda x, y: x * y[0], results, 1)
|
||||||
|
product_den = reduce(lambda x, y: x * y[1], results, 1)
|
||||||
|
|
||||||
|
# 化简分数
|
||||||
|
common_divisor = gcd(product_num, product_den)
|
||||||
|
final_answer = product_den // common_divisor
|
||||||
|
print(f"Answer: {final_answer}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
main_two()
|
||||||
Reference in New Issue
Block a user