Проект Эйлера, задача № 111. Генерация 10-значных простых чисел с большинством повторяющихся отдельных цифр

1

Я работаю над проблемой Эйлера № 111. Я создал эту программу, которая отлично работает для данного примера, но, по-видимому, не дает желаемого ответа на проблему. Вот мой исходный код в python: -

#This function generates all the primes of 4 digits with the highest repeated digits 1 to 9 and returns their sum for eg. 3313, 4441, 4111 etc.

Обратите внимание, что любая цифра от 1 до 9 может достигать 3-х раз в 4-значном простом номере. Я выделил то же самое в коде.

from more_itertools import distinct_permutations
from sympy.ntheory.primetest import isprime
def fn1to9():
    s = 0
    for digit in range(1, 10):
        for j in range(0, 10):
            permutations = list(distinct_permutations(str(digit) * 3 + str(j)))
            for perm in permutations:
                num = int("".join(perm))
                if (num > 1000000000):
                    if (isprime(num)):
                        print(num)
                        s = s + num
    return s

Эта функция предназначена для частного случая 0. Заметим, что 0 может достигать почти 2 раза в 4-значном штрихе. Я выделил номер 2 в коде.

def fnFor0():
    s = 0
    for firstDigit in range(1, 10):
        permutations = list(distinct_permutations(str(0) *2+ str(firstDigit)))
        for perm in permutations:
            for msd in range(1, 10):
                temp = list(perm)
                temp.insert(0, str(msd))
                num = int("".join(temp))
                if (num > 1000000000):
                    if (isprime(num)):
                        print(num)
                        s = s + num
    return s

Теперь эта программа работает хорошо и дает желаемую сумму 273700 как было указано в вопросе. Итак, я внес необходимые изменения и запустил их на 10 цифр. Требуемые изменения изменяли str(digit)*3 на str(digit)*9 в fn1to9 и str(digit)*2 на str(digit)*8 в fnFor0 в функции distinct_permutations() (в надежде, что 9 цифр будут повторяется для каждой цифры от 1 до 9 в простом числе и 8 0 для простого числа, содержащего 0 s). Но он не дал желаемого ответа. Затем я проверил и выяснил, что для повторных цифр 2 и 8 максимальное повторение может состоять из 8 цифр, поэтому я написал другую функцию специально для этих двух цифр, которая выглядит следующим образом:

def fnFor2and8():
    s = 0
    for digit in [2,8]:
        for firstDigit in range(0, 10):
            for secondDigit in range(0, 10):
                permutations = list(distinct_permutations(str(digit) * 8 + str(firstDigit) + str(secondDigit)))
                for perm in permutations:
                    num = int("".join(perm))
                    if (num > 1000000000):
                        if (isprime(num)):
                            print(num)
                            s = s + num
    return s

Эта функция, как и ожидалось, дает желаемые 10 цифр чисел с 2 и 8 повторяемыми ровно 8 раз. Я надеялся, что это подведение итогов из всех этих трех функций даст мне ответ, но похоже, что я пропускаю некоторые цифры. Может кто-то, пожалуйста, помогите мне указать на недостаток в моих рассуждениях или в моей программе. Заранее большое спасибо.

Теги:

1 ответ

0

Вот решение, которое я пришло к вам, я работал над этой проблемой:

import eulerlib


def compute():
    DIGITS = 10

    primes = eulerlib.list_primes(eulerlib.sqrt(10**DIGITS))

    # Only valid if 1 < n <= 10^DIGITS.
    def is_prime(n):
        end = eulerlib.sqrt(n)
        for p in primes:
            if p > end:
                break
            if n % p == 0:
                return False
        return True


    ans = 0
    # For each repeating digit
    for digit in range(10):

        # Search by the number of repetitions in decreasing order
        for rep in range(DIGITS, -1, -1):
            sum = 0
            digits = [0] * DIGITS

            # Try all possibilities for filling the non-repeating digits
            for i in range(9**(DIGITS - rep)):

                # Build initial array. For example, if DIGITS=7, digit=5, rep=4, i=123, then the array will be filled with 5,5,5,5,1,4,7.
                for j in range(rep):
                    digits[j] = digit
                temp = i
                for j in range(DIGITS - rep):
                    d = temp % 9
                    if d >= digit:  # Skip the repeating digit
                        d += 1
                    if j > 0 and d > digits[DIGITS - j]:  # If this is true, then after sorting, the array will be in an already-tried configuration
                        break
                    digits[-1 - j] = d
                    temp //= 9

                else:
                    digits.sort()  # Start at lowest permutation

                    while True:  # Go through all permutations
                        if digits[0] > 0:  # Skip if the number has a leading zero, which means it has less than DIGIT digits
                            num = int("".join(map(str, digits)))
                            if is_prime(num):
                                sum += num
                        if not eulerlib.next_permutation(digits):
                            break

            if sum > 0:  # Primes found; skip all lesser repetitions
                ans += sum
                break

    return str(ans)


if __name__ == "__main__":
    print(compute())

Ещё вопросы

Сообщество Overcoder
Наверх
Меню