Найти 200-значные простые числа, используя BigInteger

Один из способов сделать это, который абсолютно работает, — начать с 0 до того места, где вы найдете 200-значные простые числа. Для этого я написал этот метод:

var primeList = arrayListOf(BigInteger("2"))
fun findNextPrime(num : BigInteger): BigInteger {
    val n = num + BigInteger.ONE
    val sqrt = sqrt(num)
    for (bigInteger in primeList) {
        if (bigInteger > sqrt){
            return n
        }
        if (n % bigInteger == BigInteger.ZERO){
            return findNextPrime(num + BigInteger.ONE)
        }
    }
    return n;
}

Я добавляю числа, которые я нахожу, в PrimeList и проверяю только числа, меньшие, чем квадратный корень. Несмотря на то, что это был самый быстрый алгоритм, который я мог написать, но он занимает так много времени после нахождения миллиона цифр, что составляет всего 7 цифр. это доходит до 200 цифр (хотя мой ноутбук i7 8-го поколения). Итак, следующее, что я использовал, было это:

n = 2 * 3 * 5 *... + 1

ну, n является простым, и этот метод довольно быстро используется для получения высоких цифр, но нет ничего наверняка, чтобы точно добраться до 200 цифр. Я получил 198 и 201 цифру. Но нет 200, код простой, но я все равно публикую его. :

var all = BigInteger.ONE
primeList.forEach {
   all *= it
}
all++
println(all.toString().length)

кстати all += all * it не вычисляет произведение PrimeList

harold 23.04.2019 13:29
gist.github.com/domnikl/6ad30f0a6ca3228f44e8273c08dbd879 вы можете изменить код для большого целого числа.
Rahul Sharma 23.04.2019 13:37

в котлине есть понятие последовательности. Вы должны изучить это. Также 200-я цена составляет 1217, что не так уж и много, поэтому вы можете просто использовать целое число.

Rahul Sharma 23.04.2019 13:39
well n is prime ? Это неправда вообще. Не все первобытные отличаются на 1 от простого числа. Чтобы получить простое число длиной 200 цифр, единственный возможный способ — сгенерировать случайные нечетные числа такого размера и проверить их на простоту. Другими словами, ловите их
John Coleman 23.04.2019 13:55

Я только что провел тест Миллера-Рабина на двух первичных простых кандидатах, которые охватывают 200 цифр. Оба числа составные.

John Coleman 23.04.2019 14:10

Гарольд: это в цикле foreach. Так что я уверен, что это так. Рахул: не 200-й, я имел в виду 200-значный номер.

Steve Moretz 23.04.2019 16:08

@RahulKumar, пожалуйста, объясните фильтр и выход в этом основном коде, это потрясающе, еще не пробовал с bigInteger, но, честно говоря, выглядит великолепно.

Steve Moretz 23.04.2019 16:09

В продуктах @stevemoretz нет сложения, только умножение

harold 23.04.2019 16:56

@harold Вы совершенно правы. Сегодня я немного не в себе. Все *= на самом деле я хотел это написать.

Steve Moretz 23.04.2019 17:05

@RahulKumar Суть работает нормально, но не для 200 цифр. Я заставил ее работать с BigInteger, но она снова слишком медленная.

Steve Moretz 23.04.2019 17:06
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
10
633
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Неверно, что 1 + произведение первых n простых чисел всегда простое. Возможно, вы неправильно помните его роль в доказательстве того, что существует бесконечно много простых чисел. является верно, что если p_1, p_2, ..., p_n — первые n простые числа, то

p_1 * p_2 * ... * p_n + 1

является либо простым, либо содержит простой множитель, который больше любого из этих p_i, но это согласуется с тем, что число является составным. Дополнительную информацию см. в статье Википедии о первобытные.

В случае попытки набрать 200 цифр произведение первых 92 простых чисел + 1 содержит 199 цифр, а произведение первых 93 простых чисел + 1 — 201 цифру. В обоих случаях Тест Миллера-Рабина показывает, что они составные. Я не смог разложить на множители 199-значный, но 201-значный фактор как

509558935064289364432032169616857776489168568369134671296055828054188240764364761921821351373922822013621199759688858354748131233614846920025560717744496960296617420071391914813530238313960697008021211 = 11587 * 43976778723076669062918112506848863078378231498156094873224806080451216083918595142989673890905568483094951217717170825472351016968572272376418461874902646094469441621765074205016849772500275913353

С числами такой величины единственный эффективный способ получить простое число — это случайным образом сгенерировать число-кандидат целевого размера и проверить его на простоту (используя что-то вроде теста Миллера-Рабина). По теореме о простых числах 200-значных простых чисел относительно много, поэтому на практике такое простое число можно найти очень быстро. Например, сценарий Python, который я написал с помощью Миллера-Рабина, выдал следующее 200-значное простое число менее чем за секунду:

49675218696612399034240799519655205503986657506787162015105425670413948962864456158664793804627084299081036134562339483478437262146378569515417671690110863951848724044479367633926630234074394356492223

При редактировании: Вот скрипт Python, который я использовал, чтобы найти 200-значное простое число. Код был для класса, который я вел по криптографии, поэтому я написал его так, чтобы его было легко обсуждать, а не сжато или эффективно:

import random

#The following function finds s and d in
#n-1 = 2^s*d with d odd
def findSD(n):
    s = 0
    d = n-1
    while d % 2 == 0:
        s = s + 1
        d = d//2
    return s,d

def checkBase(a,n):
    s,d = findSD(n)
    x = pow(a,d,n)
    if x == 1 or x == n-1:
        return "probable prime"
    else:
        for i in range(s-1):
            x = pow(x,2,n)
            if x == 1:
                return "composite"
            elif x == n-1:
                return "probable prime"
        #if you get to this stage, -1 not reached despite s-1
        #squarings -- so must be composite
        return "composite"

def MSR(n,k):
    #Implements the Miller-Selfridge-Rabin test for primality
    for i in range(k):
        a = random.randint(2,n-2)
        if checkBase(a,n) == "composite":
            return "composite"
    #if you get here n has survived k potential witnesses, so
    return "probable prime"

#The following function is slightly different from the one discussed in class:

def prime(n):
    smallPrimes = [2,3,5,7,11,13,17,19]

    for p in smallPrimes:
        if n == p:
            return True
        elif n % p == 0:
            return False

    if MSR(n,20) == "composite":
        return False
    else:
        return True

def findPrime(maxN):
    while True:
        m = random.randint(1,maxN//2)
        n = 2*m+1
        if prime(n):
            return n

Например, findPrime(10**200) обычно дает вам 200-значное простое число (хотя возможно получение 199-значного или даже меньшего числа).

Магистр университета сказал мне, что 3 * 5 * 7 ... всегда работает. Похоже, он немного не в себе. Спасибо, что сообщили мне. И, кстати, даже обмен кодом Python может помочь, если вы не мне нравится kotlin или java :), поэтому, пожалуйста, опубликуйте это, спасибо.

Steve Moretz 23.04.2019 16:12

@stevemoretz Я добавил код. 3*5*7 ... + 1 используется как способ показать, что существуют сколь угодно большие простые числа, поэтому, если вы просто помните этот факт и давно не работали над доказательством, легко увидеть, как мелкий шрифт, что само число не обязательно простое, может потеряться.

John Coleman 23.04.2019 17:07

Извините, что вы подразумеваете под выражением вероятное простое число? Разве мы еще не уверены, что вы имеете в виду конец?

Steve Moretz 23.04.2019 17:20

@stevemoretz Тест Миллера Рабина вероятностный. Он не подтверждает, что число является простым, но может сделать вероятность ложного срабатывания произвольно низкой (ниже, чем вероятность аппаратной ошибки при выполнении детерминированного алгоритма).

John Coleman 23.04.2019 17:27

Спасибо. Также похоже, что Миллер Рабин уже является функцией в родной Java! Я просто не совсем понимаю ее. Если бы вы могли объяснить это немного подробнее и менее сложно, это было бы здорово. Я просто программист, а не в математике. действительно майор.

Steve Moretz 23.04.2019 17:37

@stevemoretz Нет простого способа объяснить Миллер-Рабин. Текст, который я использовал в прошлый раз, когда я вел класс, сделал достойную работу по объяснению математики: «Криптография с открытым ключом» Линн Баттен. Эта книга предназначалась в основном для программистов, поэтому в ней не делается много фоновых предположений.

John Coleman 23.04.2019 18:06

Вы знаете, в чем вы правы. Может быть, это просто питон усложняет для меня. Потому что я обычно не скриптер на питон. После того, как я написал то же самое в java, теперь это имеет гораздо больше смысла. Еще раз спасибо, я принял ваш ответ но также добавит метод, который делает это в java по умолчанию.

Steve Moretz 23.04.2019 18:47

Технически существуют конструктивные методы, такие как Маурер и Шоу-Тейлор, которые производят проверенные простые числа, в дополнение к обычным методам, включающим отбор + тестирование PRP. Также можно выполнить доказательство простоты общей формы для 200-значного числа довольно быстро (менее 1 секунды), хотя люди редко беспокоятся.

DanaJ 25.04.2019 08:05

в классе BigInteger есть метод:

isProbablePrime(int)

он использует тот же алгоритм, что и наш друг, здесь: Но он также проверяет результат другим алгоритмом. Он работает довольно аккуратно.

Другие вопросы по теме