Compare commits

..

5 Commits

Author SHA1 Message Date
233fc85708 Fix import of utils 2026-04-11 16:04:58 +02:00
2fb728a4ba Refactor problem 2026-04-11 16:04:07 +02:00
e900cb117e Refactor for efficiency 2026-04-11 16:03:17 +02:00
a036c30fc4 Refactor without building the whole list 2026-04-11 15:35:30 +02:00
8c3da33225 Refactor with itertools 2026-04-11 15:27:41 +02:00
5 changed files with 36 additions and 23 deletions

View File

@@ -22,7 +22,7 @@ def create_problem():
https://projecteuler.net/problem={args["problem"]} https://projecteuler.net/problem={args["problem"]}
""" """
from utils import timeit from project_euler_python.utils import timeit
@timeit("Problem {(args["problem"]):0>3}") @timeit("Problem {(args["problem"]):0>3}")

View File

@@ -34,7 +34,7 @@ def compute():
names = sorted(f.read().replace('"', "").split(",")) names = sorted(f.read().replace('"', "").split(","))
ans = 0 ans = 0
for idx, name in enumerate(names, 1): for idx, name in enumerate(names, start=1):
ans += sum(ord(char) - 64 for char in name) * idx ans += sum(ord(char) - 64 for char in name) * idx
return ans return ans

View File

@@ -9,9 +9,21 @@ Solution for problem 023 of Project Euler
https://projecteuler.net/problem=23 https://projecteuler.net/problem=23
""" """
from itertools import combinations_with_replacement
from project_euler_python.utils import timeit from project_euler_python.utils import timeit
def _get_abundant_numbers(limit):
divisor_sums = [0 for _ in range(limit)]
for divisor in range(1, limit):
for multiple in range(divisor * 2, limit, divisor):
divisor_sums[multiple] += divisor
return [number for number in range(1, limit) if divisor_sums[number] > number]
@timeit("Problem 023") @timeit("Problem 023")
def compute(): def compute():
""" """
@@ -35,25 +47,19 @@ def compute():
sum of two abundant numbers. sum of two abundant numbers.
""" """
limit = 28124 limit = 28123 + 1
divisor_sum = [0] * limit abundant_numbers = _get_abundant_numbers(limit)
for i in range(1, limit):
for j in range(i * 2, limit, i):
divisor_sum[j] += i
abundant_nums = [i for (i, x) in enumerate(divisor_sum) if x > i] expressible_sums = {
first + second
for first, second in combinations_with_replacement(
abundant_numbers,
2,
)
if first + second < limit
}
expressible = [False] * limit return sum(number for number in range(1, limit) if number not in expressible_sums)
for i in abundant_nums:
for j in abundant_nums:
if i + j < limit:
expressible[i + j] = True
else:
break
ans = sum(i for (i, x) in enumerate(expressible) if not x)
return ans
if __name__ == "__main__": if __name__ == "__main__":

View File

@@ -9,7 +9,7 @@ Solution for problem 024 of Project Euler
https://projecteuler.net/problem=24 https://projecteuler.net/problem=24
""" """
from itertools import permutations from itertools import islice, permutations
from project_euler_python.utils import timeit from project_euler_python.utils import timeit
@@ -28,9 +28,10 @@ def compute():
0, 1, 2, 3, 4, 5, 6, 7, 8 and 9? 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9?
""" """
limit = 1_000_000
digits = list(range(10)) digits = list(range(10))
_permutations = list(permutations(digits)) millionth_permutation = next(islice(permutations(digits), limit - 1, limit))
ans = "".join(str(digit) for digit in _permutations[999_999]) ans = "".join(str(digit) for digit in millionth_permutation)
return ans return ans

View File

@@ -37,11 +37,17 @@ def compute():
cycle_length = 0 cycle_length = 0
ans = 0 ans = 0
# Because denominators with factor 2 contribute only to the terminating
# part of a decimal. The repeating behavior comes from the part of the
# denominator that is coprime with 10, so evens are skipped
for number in range(3, 1000, 2): for number in range(3, 1000, 2):
if number % 5 == 0: if number % 5 == 0:
continue continue
p = 1 p = 1
while 10**p % number != 1: remainder = 10 % number
while remainder != 1:
# avoid huge exponentiation
remainder = (remainder * 10) % number
p += 1 p += 1
if p > cycle_length: if p > cycle_length:
cycle_length, ans = p, number cycle_length, ans = p, number