From d1af6aa88034ca4dc1f4ef5ee9503b8341f60aae Mon Sep 17 00:00:00 2001 From: Sidney Zhang Date: Wed, 26 Nov 2025 15:31:14 +0800 Subject: [PATCH] created and first commit(3 solusions) --- .gitignore | 10 +++ .python-version | 1 + README.md | 6 ++ license | 18 ++++ main.py | 6 ++ pyproject.toml | 7 ++ solutions/0000.zero/euler_0.py | 26 ++++++ solutions/0001.multiples/euler_1.py | 26 ++++++ solutions/0002.even_fibonacci/euler_2.py | 48 +++++++++++ solutions/0003.largestprime/euler_3.py | 103 +++++++++++++++++++++++ uv.lock | 8 ++ 11 files changed, 259 insertions(+) create mode 100644 .gitignore create mode 100644 .python-version create mode 100644 README.md create mode 100644 license create mode 100644 main.py create mode 100644 pyproject.toml create mode 100644 solutions/0000.zero/euler_0.py create mode 100644 solutions/0001.multiples/euler_1.py create mode 100644 solutions/0002.even_fibonacci/euler_2.py create mode 100644 solutions/0003.largestprime/euler_3.py create mode 100644 uv.lock diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..505a3b1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# Python-generated files +__pycache__/ +*.py[oc] +build/ +dist/ +wheels/ +*.egg-info + +# Virtual environments +.venv diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..24ee5b1 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.13 diff --git a/README.md b/README.md new file mode 100644 index 0000000..d036a16 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# Solusions for Project Euler + +主要记录一下解决 [Project Euler](https://projecteuler.net/) 问题的方法,自娱自乐成分较大, +也会有一些新奇的想法。主要使用 Python 解决,也会有 Haskell 、 Rust 或者 Lean4 的解决方法。 + +项目使用 `uv` 进行管理,毕竟主要还是使用 Python来写的。 diff --git a/license b/license new file mode 100644 index 0000000..389fbce --- /dev/null +++ b/license @@ -0,0 +1,18 @@ +Copyright 2025 SidneyZhang + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the “Software”), +to deal in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, subject +to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies +or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/main.py b/main.py new file mode 100644 index 0000000..686fb6b --- /dev/null +++ b/main.py @@ -0,0 +1,6 @@ +def main(): + print("Hello from projecteuler!") + + +if __name__ == "__main__": + main() diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..085c5c4 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,7 @@ +[project] +name = "projecteuler" +version = "0.1.0" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.12" +dependencies = [] diff --git a/solutions/0000.zero/euler_0.py b/solutions/0000.zero/euler_0.py new file mode 100644 index 0000000..c0fd7d3 --- /dev/null +++ b/solutions/0000.zero/euler_0.py @@ -0,0 +1,26 @@ +""" +Project Euler Problem 0 : +Find the sum of all the odd squares which do not exceed 764000. + +这是注册问题。 +""" + +UP_NUM = 764000 + + +def is_even(num: int) -> bool: + """Check if a number is even.""" + return num & 1 == 0 + + +def main(): + res: list[int] = [] + for i in range(UP_NUM): + t = (i + 1) ** 2 + if not is_even(t): + res.append(t) + print(sum(res)) + + +if __name__ == "__main__": + main() diff --git a/solutions/0001.multiples/euler_1.py b/solutions/0001.multiples/euler_1.py new file mode 100644 index 0000000..cf87639 --- /dev/null +++ b/solutions/0001.multiples/euler_1.py @@ -0,0 +1,26 @@ +""" +Project Euler Problem 1 : +Find the sum of all the multiples of 3 or 5 below 1000. +""" + +UP_NUM = 1000 + + +def condition(num: int) -> bool: + if num % 3 == 0: + return True + elif num % 5 == 0: + return True + return False + + +def main(): + res = [] + for i in range(1, UP_NUM): + if condition(i): + res.append(i) + print(sum(res)) + + +if __name__ == "__main__": + main() diff --git a/solutions/0002.even_fibonacci/euler_2.py b/solutions/0002.even_fibonacci/euler_2.py new file mode 100644 index 0000000..849f55b --- /dev/null +++ b/solutions/0002.even_fibonacci/euler_2.py @@ -0,0 +1,48 @@ +""" +Even Fibonacci Numbers + +Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be: +1, 2, 3, 5, 8, 13, 21, 34, 55, 89 +By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms. +""" + +UP_NUM = 4000000 + + +def is_even(num: int) -> bool: + """Check if a number is even.""" + return num & 1 == 0 + + +""" +下面这个方法实在太慢,计算400万项还会内存溢出。 +```python +def fibonacci_sequence(n: int) -> list[int]: + a, b = 1, 2 + res = [a, b] + while b <= n: + a, b = b, a + b + res.append(b) + return res + + +def main(): + fib_seq = fibonacci_sequence(UP_NUM) + even_sum = sum(num for num in fib_seq if is_even(num)) + print(even_sum) +``` +""" + + +def even_fibonacci(limit: int) -> int: + a, b = 1, 2 + even_sum = 0 + while b <= limit: + if is_even(b): + even_sum += b + a, b = b, a + b + return even_sum + + +if __name__ == "__main__": + print(even_fibonacci(UP_NUM)) diff --git a/solutions/0003.largestprime/euler_3.py b/solutions/0003.largestprime/euler_3.py new file mode 100644 index 0000000..7901d8c --- /dev/null +++ b/solutions/0003.largestprime/euler_3.py @@ -0,0 +1,103 @@ +import random +from math import gcd +from typing import List, Set + + +def is_probable_prime(n: int, trials: int = 10) -> bool: + """Miller-Rabin素性测试(快速判断是否为质数)""" + if n < 2: + return False + if n in (2, 3): + return True + if n % 2 == 0: + return False + + # 将 n-1 写成 d * 2^s 的形式 + d = n - 1 + s = 0 + while d % 2 == 0: + d //= 2 + s += 1 + + # 测试 + for _ in range(trials): + a = random.randrange(2, n - 1) + x = pow(a, d, n) + if x == 1 or x == n - 1: + continue + for _ in range(s - 1): + x = pow(x, 2, n) + if x == n - 1: + break + else: + return False + return True + + +def pollards_rho(n: int, max_iter: int = 100000) -> int: + """ + Pollard's Rho 算法:返回n的一个非平凡因子 + + Args: + n: 待分解的合数 + max_iter: 最大迭代次数防止无限循环 + + Returns: + n的一个因子(可能是质数也可能是合数) + 若失败返回None + """ + if n % 2 == 0: + return 2 + + # 随机生成多项式 f(x) = x^2 + c (mod n) + c = random.randrange(1, n - 1) + + def f(x): + return (pow(x, 2, n) + c) % n + + # Floyd 判圈算法 + x = random.randrange(2, n - 1) + y = x + d = 1 + + iter_count = 0 + while d == 1 and iter_count < max_iter: + x = f(x) # 乌龟:走一步 + y = f(f(y)) # 兔子:走两步 + d = gcd(abs(x - y), n) + iter_count += 1 + + if d == n: + # 失败,尝试其他参数(递归或返回None) + return pollards_rho(n, max_iter) if max_iter > 1000 else None + + return d + + +def factorize(n: int | None) -> List[int | None]: + """ + 完整因数分解:递归分解所有质因数 + + Args: + n: 待分解的正整数 + + Returns: + 质因数列表(可能含重复) + """ + if n == 1: + return [] + + # 如果是质数,直接返回 + if is_probable_prime(n): + return [n] + + # 获取一个因子 + factor = pollards_rho(n) + + # 递归分解 + return factorize(factor) + factorize(n // factor) + + +def get_prime_factors(n: int) -> Set[int | None]: + """获取所有不重复的质因数""" + return set(factorize(n)) diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..66d8ee2 --- /dev/null +++ b/uv.lock @@ -0,0 +1,8 @@ +version = 1 +revision = 3 +requires-python = ">=3.12" + +[[package]] +name = "projecteuler" +version = "0.1.0" +source = { virtual = "." }