diff --git a/solutions/0033.DigitCancelling/euler_33.py b/solutions/0033.DigitCancelling/euler_33.py new file mode 100644 index 0000000..9252e11 --- /dev/null +++ b/solutions/0033.DigitCancelling/euler_33.py @@ -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()