mirror of
https://github.com/TheAlgorithms/Python.git
synced 2024-12-18 09:10:16 +00:00
bcfca67faa
* [mypy] fix type annotations for problem003/sol1 and problem003/sol3 * [mypy] fix type annotations for project euler problem007/sol2 * [mypy] fix type annotations for project euler problem008/sol2 * [mypy] fix type annotations for project euler problem009/sol1 * [mypy] fix type annotations for project euler problem014/sol1 * [mypy] fix type annotations for project euler problem 025/sol2 * [mypy] fix type annotations for project euler problem026/sol1.py * [mypy] fix type annotations for project euler problem037/sol1 * [mypy] fix type annotations for project euler problem044/sol1 * [mypy] fix type annotations for project euler problem046/sol1 * [mypy] fix type annotations for project euler problem051/sol1 * [mypy] fix type annotations for project euler problem074/sol2 * [mypy] fix type annotations for project euler problem080/sol1 * [mypy] fix type annotations for project euler problem099/sol1 * [mypy] fix type annotations for project euler problem101/sol1 * [mypy] fix type annotations for project euler problem188/sol1 * [mypy] fix type annotations for project euler problem191/sol1 * [mypy] fix type annotations for project euler problem207/sol1 * [mypy] fix type annotations for project euler problem551/sol1
114 lines
3.0 KiB
Python
114 lines
3.0 KiB
Python
"""
|
|
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 __future__ import annotations
|
|
|
|
from collections import Counter
|
|
|
|
|
|
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 = str(number)
|
|
replacements = []
|
|
digits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
|
|
|
|
for duplicate in Counter(number_str) - Counter(set(number_str)):
|
|
family = [int(number_str.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)
|
|
|
|
return -1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
print(solution())
|