Skip to content

Commit 542b400

Browse files
committed
Add solution for the euler project problem 111.
1 parent 0c8cf8e commit 542b400

File tree

2 files changed

+100
-0
lines changed

2 files changed

+100
-0
lines changed

project_euler/problem_111/__init__.py

Whitespace-only changes.

project_euler/problem_111/sol1.py

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
"""
2+
Project Euler Problem 111: https://projecteuler.net/problem=111
3+
4+
Primes with Runs
5+
6+
First, note that for sequence of 10 digits, M(4,d) is 8 or 9.
7+
Start by constructing prime list up to sqrt(n), which are used to check if
8+
number is prime.
9+
Then iterate over possible combinations of numbers checking each if prime.
10+
11+
"""
12+
13+
from numpy import sqrt
14+
15+
16+
def generate_primes(n: int):
17+
"""
18+
Calculates the list of primes up to and including n.
19+
20+
>>> generate_primes(6)
21+
[2, 3, 5]
22+
"""
23+
primes = [True] * (n + 1)
24+
primes[0] = primes[1] = False
25+
for i in range(2, int(sqrt(n + 1)) + 1):
26+
if primes[i]:
27+
j = i * i
28+
while j <= n:
29+
primes[j] = False
30+
j += i
31+
primes_list = []
32+
for i in range(2, len(primes)):
33+
if primes[i]:
34+
primes_list += [i]
35+
return primes_list
36+
37+
38+
def is_prime(n, primes_all):
39+
"""
40+
Check in int n is prime using primes_all list of relatively small primes
41+
compared to n.
42+
43+
>>> is_prime(5, [2, 3])
44+
True
45+
"""
46+
return all(n % p != 0 for p in primes_all)
47+
48+
49+
def solution(n: int = 10000000000) -> int:
50+
"""
51+
Check each possible combination if it is prime.
52+
53+
54+
>>> solution(10000)
55+
273700
56+
"""
57+
primes_all = generate_primes(int(sqrt(n)) + 1)
58+
total = 0
59+
60+
n_zeros = len(str(n)) - 3
61+
for i in range(1, 10):
62+
for j in range(1, 10):
63+
num = int(str(i) + "0" * n_zeros + str(j))
64+
if is_prime(num, primes_all):
65+
total += num
66+
67+
one_digit = set()
68+
n_dig = len(str(n)) - 2
69+
for i in range(1, 10):
70+
for j in range(n_dig + 1):
71+
for k in range(10):
72+
num = int(str(i) * j + str(k) + str(i) * (n_dig - j))
73+
if is_prime(num, primes_all):
74+
one_digit.add(i)
75+
total += num
76+
77+
n_dig = len(str(n)) - 3
78+
two_dig = {1, 2, 3, 4, 5, 6, 7, 8, 9} - one_digit
79+
for i in list(two_dig): # main digit
80+
for j in range(n_dig + 1):
81+
for k in range(n_dig + 1 - j):
82+
for m1 in range(10): # first changing digit
83+
if m1 == 0 and j == 0:
84+
continue
85+
for m2 in range(10): # second changing digit
86+
num = int(
87+
str(i) * j
88+
+ str(m1)
89+
+ str(i) * k
90+
+ str(m2)
91+
+ str(i) * (n_dig - j - k)
92+
)
93+
if is_prime(num, primes_all):
94+
total += num
95+
96+
return total
97+
98+
99+
if __name__ == "__main__":
100+
print(f"{solution() = }")

0 commit comments

Comments
 (0)