Один из способов сделать это, который абсолютно работает, — начать с 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)
в котлине есть понятие последовательности. Вы должны изучить это. Также 200-я цена составляет 1217, что не так уж и много, поэтому вы можете просто использовать целое число.
well n is prime ? Это неправда вообще. Не все первобытные отличаются на 1 от простого числа. Чтобы получить простое число длиной 200 цифр, единственный возможный способ — сгенерировать случайные нечетные числа такого размера и проверить их на простоту. Другими словами, ловите их
Я только что провел тест Миллера-Рабина на двух первичных простых кандидатах, которые охватывают 200 цифр. Оба числа составные.
Гарольд: это в цикле foreach. Так что я уверен, что это так. Рахул: не 200-й, я имел в виду 200-значный номер.
@RahulKumar, пожалуйста, объясните фильтр и выход в этом основном коде, это потрясающе, еще не пробовал с bigInteger, но, честно говоря, выглядит великолепно.
В продуктах @stevemoretz нет сложения, только умножение
@harold Вы совершенно правы. Сегодня я немного не в себе. Все *= на самом деле я хотел это написать.
@RahulKumar Суть работает нормально, но не для 200 цифр. Я заставил ее работать с BigInteger, но она снова слишком медленная.




Неверно, что 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 :), поэтому, пожалуйста, опубликуйте это, спасибо.
@stevemoretz Я добавил код. 3*5*7 ... + 1 используется как способ показать, что существуют сколь угодно большие простые числа, поэтому, если вы просто помните этот факт и давно не работали над доказательством, легко увидеть, как мелкий шрифт, что само число не обязательно простое, может потеряться.
Извините, что вы подразумеваете под выражением вероятное простое число? Разве мы еще не уверены, что вы имеете в виду конец?
@stevemoretz Тест Миллера Рабина вероятностный. Он не подтверждает, что число является простым, но может сделать вероятность ложного срабатывания произвольно низкой (ниже, чем вероятность аппаратной ошибки при выполнении детерминированного алгоритма).
Спасибо. Также похоже, что Миллер Рабин уже является функцией в родной Java! Я просто не совсем понимаю ее. Если бы вы могли объяснить это немного подробнее и менее сложно, это было бы здорово. Я просто программист, а не в математике. действительно майор.
@stevemoretz Нет простого способа объяснить Миллер-Рабин. Текст, который я использовал в прошлый раз, когда я вел класс, сделал достойную работу по объяснению математики: «Криптография с открытым ключом» Линн Баттен. Эта книга предназначалась в основном для программистов, поэтому в ней не делается много фоновых предположений.
Вы знаете, в чем вы правы. Может быть, это просто питон усложняет для меня. Потому что я обычно не скриптер на питон. После того, как я написал то же самое в java, теперь это имеет гораздо больше смысла. Еще раз спасибо, я принял ваш ответ но также добавит метод, который делает это в java по умолчанию.
Технически существуют конструктивные методы, такие как Маурер и Шоу-Тейлор, которые производят проверенные простые числа, в дополнение к обычным методам, включающим отбор + тестирование PRP. Также можно выполнить доказательство простоты общей формы для 200-значного числа довольно быстро (менее 1 секунды), хотя люди редко беспокоятся.
в классе BigInteger есть метод:
isProbablePrime(int)
он использует тот же алгоритм, что и наш друг, здесь: Но он также проверяет результат другим алгоритмом. Он работает довольно аккуратно.
кстати
all += all * itне вычисляет произведение PrimeList