mirror of
https://github.com/TheAlgorithms/Python.git
synced 2025-02-17 14:58:10 +00:00
Add project euler problem 51 (#3018)
* Add project euler problem 51 * Apply review suggestions
This commit is contained in:
parent
695217e964
commit
50d7ed8417
0
project_euler/problem_51/__init__.py
Normal file
0
project_euler/problem_51/__init__.py
Normal file
111
project_euler/problem_51/sol1.py
Normal file
111
project_euler/problem_51/sol1.py
Normal file
|
@ -0,0 +1,111 @@
|
|||
"""
|
||||
https://projecteuler.net/problem=51
|
||||
Prime digit replacements
|
||||
Problem 51
|
||||
|
||||
By replacing the 1st digit of the 2-digit number *3, it turns out that six of
|
||||
the nine possible values: 13, 23, 43, 53, 73, and 83, are all prime.
|
||||
|
||||
By replacing the 3rd and 4th digits of 56**3 with the same digit, this 5-digit
|
||||
number is the first example having seven primes among the ten generated numbers,
|
||||
yielding the family: 56003, 56113, 56333, 56443, 56663, 56773, and 56993.
|
||||
Consequently 56003, being the first member of this family, is the smallest prime
|
||||
with this property.
|
||||
|
||||
Find the smallest prime which, by replacing part of the number (not necessarily
|
||||
adjacent digits) with the same digit, is part of an eight prime value family.
|
||||
"""
|
||||
|
||||
from collections import Counter
|
||||
from typing import List
|
||||
|
||||
|
||||
def prime_sieve(n: int) -> List[int]:
|
||||
"""
|
||||
Sieve of Erotosthenes
|
||||
Function to return all the prime numbers up to a certain number
|
||||
https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
|
||||
|
||||
>>> prime_sieve(3)
|
||||
[2]
|
||||
|
||||
>>> prime_sieve(50)
|
||||
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
|
||||
"""
|
||||
is_prime = [True] * n
|
||||
is_prime[0] = False
|
||||
is_prime[1] = False
|
||||
is_prime[2] = True
|
||||
|
||||
for i in range(3, int(n ** 0.5 + 1), 2):
|
||||
index = i * 2
|
||||
while index < n:
|
||||
is_prime[index] = False
|
||||
index = index + i
|
||||
|
||||
primes = [2]
|
||||
|
||||
for i in range(3, n, 2):
|
||||
if is_prime[i]:
|
||||
primes.append(i)
|
||||
|
||||
return primes
|
||||
|
||||
|
||||
def digit_replacements(number: int) -> List[List[int]]:
|
||||
"""
|
||||
Returns all the possible families of digit replacements in a number which
|
||||
contains at least one repeating digit
|
||||
|
||||
>>> digit_replacements(544)
|
||||
[[500, 511, 522, 533, 544, 555, 566, 577, 588, 599]]
|
||||
|
||||
>>> digit_replacements(3112)
|
||||
[[3002, 3112, 3222, 3332, 3442, 3552, 3662, 3772, 3882, 3992]]
|
||||
"""
|
||||
number = str(number)
|
||||
replacements = []
|
||||
digits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
|
||||
|
||||
for duplicate in Counter(number) - Counter(set(number)):
|
||||
family = [int(number.replace(duplicate, digit)) for digit in digits]
|
||||
replacements.append(family)
|
||||
|
||||
return replacements
|
||||
|
||||
|
||||
def solution(family_length: int = 8) -> int:
|
||||
"""
|
||||
Returns the solution of the problem
|
||||
|
||||
>>> solution(2)
|
||||
229399
|
||||
|
||||
>>> solution(3)
|
||||
221311
|
||||
"""
|
||||
numbers_checked = set()
|
||||
|
||||
# Filter primes with less than 3 replaceable digits
|
||||
primes = {
|
||||
x for x in set(prime_sieve(1_000_000)) if len(str(x)) - len(set(str(x))) >= 3
|
||||
}
|
||||
|
||||
for prime in primes:
|
||||
if prime in numbers_checked:
|
||||
continue
|
||||
|
||||
replacements = digit_replacements(prime)
|
||||
|
||||
for family in replacements:
|
||||
numbers_checked.update(family)
|
||||
primes_in_family = primes.intersection(family)
|
||||
|
||||
if len(primes_in_family) != family_length:
|
||||
continue
|
||||
|
||||
return min(primes_in_family)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(solution())
|
Loading…
Reference in New Issue
Block a user