新增欧拉第33题“数字约分分数”双解法实现

This commit is contained in:
2026-01-03 22:03:35 +08:00
parent ff1c6bffeb
commit 0be6fed37c

View 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()