Skip to content

Commit 3eb0fc2

Browse files
Hyftarstokhos
authored andcommitted
Fixes: TheAlgorithms#3163 - Add new solution for problem 234 (TheAlgorithms#3177)
* Fixes: TheAlgorithms#3163 - Add new solution for problem 234 * Apply review suggestions
1 parent a4350ed commit 3eb0fc2

File tree

1 file changed

+95
-32
lines changed

1 file changed

+95
-32
lines changed

Diff for: project_euler/problem_234/sol1.py

+95-32
Original file line numberDiff line numberDiff line change
@@ -17,40 +17,103 @@
1717
What is the sum of all semidivisible numbers not exceeding 999966663333 ?
1818
"""
1919

20+
import math
2021

21-
def fib(a, b, n):
22-
23-
if n == 1:
24-
return a
25-
elif n == 2:
26-
return b
27-
elif n == 3:
28-
return str(a) + str(b)
29-
30-
temp = 0
31-
for x in range(2, n):
32-
c = str(a) + str(b)
33-
temp = b
34-
b = c
35-
a = temp
36-
return c
37-
38-
39-
def solution(n):
40-
"""Returns the sum of all semidivisible numbers not exceeding n."""
41-
semidivisible = []
42-
for x in range(n):
43-
l = [i for i in input().split()] # noqa: E741
44-
c2 = 1
45-
while 1:
46-
if len(fib(l[0], l[1], c2)) < int(l[2]):
47-
c2 += 1
48-
else:
22+
23+
def prime_sieve(n: int) -> list:
24+
"""
25+
Sieve of Erotosthenes
26+
Function to return all the prime numbers up to a certain number
27+
https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
28+
>>> prime_sieve(3)
29+
[2]
30+
>>> prime_sieve(50)
31+
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
32+
"""
33+
is_prime = [True] * n
34+
is_prime[0] = False
35+
is_prime[1] = False
36+
is_prime[2] = True
37+
38+
for i in range(3, int(n ** 0.5 + 1), 2):
39+
index = i * 2
40+
while index < n:
41+
is_prime[index] = False
42+
index = index + i
43+
44+
primes = [2]
45+
46+
for i in range(3, n, 2):
47+
if is_prime[i]:
48+
primes.append(i)
49+
50+
return primes
51+
52+
53+
def solution(limit: int = 999_966_663_333) -> int:
54+
"""
55+
Computes the solution to the problem up to the specified limit
56+
>>> solution(1000)
57+
34825
58+
59+
>>> solution(10_000)
60+
1134942
61+
62+
>>> solution(100_000)
63+
36393008
64+
"""
65+
primes_upper_bound = math.floor(math.sqrt(limit)) + 100
66+
primes = prime_sieve(primes_upper_bound)
67+
68+
matches_sum = 0
69+
prime_index = 0
70+
last_prime = primes[prime_index]
71+
72+
while (last_prime ** 2) <= limit:
73+
next_prime = primes[prime_index + 1]
74+
75+
lower_bound = last_prime ** 2
76+
upper_bound = next_prime ** 2
77+
78+
# Get numbers divisible by lps(current)
79+
current = lower_bound + last_prime
80+
while upper_bound > current <= limit:
81+
matches_sum += current
82+
current += last_prime
83+
84+
# Reset the upper_bound
85+
while (upper_bound - next_prime) > limit:
86+
upper_bound -= next_prime
87+
88+
# Add the numbers divisible by ups(current)
89+
current = upper_bound - next_prime
90+
while current > lower_bound:
91+
matches_sum += current
92+
current -= next_prime
93+
94+
# Remove the numbers divisible by both ups and lps
95+
current = 0
96+
while upper_bound > current <= limit:
97+
if current <= lower_bound:
98+
# Increment the current number
99+
current += last_prime * next_prime
100+
continue
101+
102+
if current > limit:
49103
break
50-
semidivisible.append(fib(l[0], l[1], c2 + 1)[int(l[2]) - 1])
51-
return semidivisible
104+
105+
# Remove twice since it was added by both ups and lps
106+
matches_sum -= current * 2
107+
108+
# Increment the current number
109+
current += last_prime * next_prime
110+
111+
# Setup for next pair
112+
last_prime = next_prime
113+
prime_index += 1
114+
115+
return matches_sum
52116

53117

54118
if __name__ == "__main__":
55-
for i in solution(int(str(input()).strip())):
56-
print(i)
119+
print(solution())

0 commit comments

Comments
 (0)