Программирование игр и головоломок
Шрифт:
n = p * q,
то либо p = q, либо один из сомножителей больше другого, так что можно считать, что p — делитель, q — частное и p <= q. Поэтому будем делить n на последовательно возрастающие простые числа, для которых частное больше или равно делителю. Так как мы не располагаем таблицей простых чисел, то используем последовательность Делителей, которая заведомо содержит все простые числа, например, последовательность нечетных чисел или лучше целых чисел вида 6k ± 1.
Число операций растет как квадратный корень из n. Если вы добавите к n
8
Да и от языка, который вы используете. — Примеч. ред.
Таким образом, вы должны бороться со следующими трудностями:
— точность вашего компьютера. Вам нужно иметь возможность делать вычисления с повышенной точностью, а это очень дорогостояще по времени;
— число требуемых операций;
— доверие к вашей программе. Если ваша машина сообщает вам, что
9873564383 = 631181 * 15643,
то вы, вероятно, сможете проверить этот результат на вашем микрокалькуляторе, А если компьютер сообщит вам, что 9873564401 — простое число, то как вы это проверите? Проделав вычисления на руках?
Вот основы метода Ж.-М. Полларда [POL].
По данному числу n (нечетному натуральному) строится последовательность по описанному ниже правилу:
— первый член последовательности равен 2;
— следующий за x элемент равен x^2 - 1 по модулю n (остатку от деления x^2 - 1 на n).
Оказывается, что эта последовательность периодична. Это легко видеть. Остаток от деления на n есть неотрицательное целое, меньшее n, поэтому не может быть более n различных остатков. Поэтому неизбежно, что как только число членов превысит n, среди членов последовательности мы получим два одинаковых, что и означает периодичность последовательности. Но она может оказаться периодической с намного более коротким периодом, чем n. Вот, например, последовательность для n = 137:
a1 = 2
a2 = 3
a3 = 8
a4 = 63
a5 = 132
a6 = 24
a7 = 27
a8 = 43
a9 = 67
a10 = 104
a11 = 129
a12 = 63 = a4
Последовательность периодична с периодом 8.
Пусть дана последовательность, вычисленная для некоторого n. Предположим, что n делится на s, и что соответствующая числу s последовательность периодична с периодом p.
Для достаточно большого i имеем ai+p = ai по модулю p, следовательно, ai+p – ai делится на p. Так как, кроме того, и n делится на p, то наибольший общий делитель (НОД) чисел ai+p– ai
9
Повторим эти рассуждения чуть более подробно. Пусть
a1 = 2, ai+1 = ai^2 - 1 mod n,
b1 = 2, bi+1 = bi^2 mod s
— последовательности, соответствующие числам n и s соответственно. Тогда легко доказать по индукции, что bi = ai mod s. Одним из периодов последовательности {аi} является n. Значит, n является периодом и для последовательности {bi}. Известно, что любой период последовательности кратен ее минимальному периоду, Так как p, по определению, является минимальным периодом последовательности bi, то n делится на p. — Примеч. ред.
Построим последовательность Полларда для n = 22879:
a1 = 2
a2 = 3
a3 = 8
a4 = 63
a5 = 3968
a6 = 4271
a7 = 6877
a8 = 2235
a9 = 7602
a10 = 20928
a11 = 8486
a12 = 11982
НОД чисел a12– a4 и n = 22879 есть 137, делитель числа n.
Если мы способны сказать, становится ли данная последовательность периодической (головоломка 1), то мы располагаем быстрым методом определения, имеет ли данное число делитель. Можете играть. Это не такая уж простая программа…
Есть тест на простоту числа, основанный на так называемой малой теореме Ферма: если n — простое, причем число n не является делителем a, то
an– 1 = 1 по модулю n.
Представим n в виде n = 2sm + 1. Назовем число n сильно псевдопростым по основанию a, если выполнено одно из следующих двух условий:
либо am = 1 по модулю n,
либо am2r = n– 1 по модулю n = 2sm + 1 для некоторого r, 0 <= r < s.
Очень мало сильно псевдопростых чисел, не являющихся простыми; так
2047 = 23 * 89 — сильно псевдопросто по основанию 2,