Числами Мерсенна, как известно, называются числа Мn = 2n-1. Как следует из формулы разложения двучлена
an-bn, они могут быть простыми лишь при простом п. При четном
n выражение 2n-1 можно разложить на множители, пользуясь, например,
формулой для разности квадратов. Вот первые три числа Мерсенна: М1= 1; M2 == 3;
M3 = 7. Дальнейшие вычисления поручим системе Mathematica. Для этого напишем программу для разложения чисел Мерсенна, получающихся при
n = 1,2, 3, ..., k.
Сначала давайте решим какой-нибудь конкретный пример. Разложим, например, на множители число
M67. Марен Мерсенн в 1644 году высказал мнение, что это число простое. Однако ошибочность этого утверждения была установлена Э. Люка только в 1875 году. Давайте же посмотрим, сколько времени потребуется системе Mathematica, чтобы справиться с более трудной задачей — разложением на простые множители. Итак, вводим запрос
Factorlnteger[ 2^67-1 ] . и мгновенно получаем ответ.
{193707721,1}, {761838257287,1}}
Dо[ Print [n, ": ", Factor-Integer [2^n-1] ],{n,257}]
1 {}
2 {{3,1}}
3 {{7,1}}
4 {{3,1},{5,1}}
5 {{31,1}}
6 {{3,2},{7,1.}}
7 {{127,1}}
8 {{3,1},{5,1},{17,1}}
9 {{7,1},{73,1}}
10 {{3,1},{11,1},{31,1}}
11 {{23,1},{89,1}}
12 {{3,2},{5,1},{7,1},{13,1}}
13 {{8191,1}}
14 {{3,1},{43,1},{127,1}}
15 {{7,1},{31,1},{151,1}}
16 {{3,1},{5,1},{17,1},{257,1}}
17 {{131071,1}}
18 {{3,3},{7,1},{19,1},{73,1}}
19 {{524287,1}}
20 {{3,1},{5,2},{11,1},(31,1),{41,1}}
Sub Factorization() i
'Обработка списка множителей
Dim strTemp As String
Dim Msg, Style, Title, Help, Ctxt, Response, MyString, R
Msg = "Хотите продолжить ?" ' Вопрос
Style = vbYesNo + vbCritical + vbDefaultButton2 ' Кнопки
Title = "Разложение на множители"' Заголовок окна
Response = vbYes ' Пока ошибки не обнаружены
Selection.Find.ClearFormatting
'Очистка формата в поле поиска With Selection.Find
.Text = "{" ' Что ищем - открывающую скобку
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False End With Selection.Find.Execute
'Находим открывающую фигурную скобку списка
strTemp = Selection.Text
If strTemp = "{" Then
' Если нашли скобку, обрабатываем список
Selection.Delete Unit:=wdCharacter, Count:=1
' Удаляем скобку Do '
В цикле обрабатываем все элементы списка
Response = Multiplier '
Обработка множителя и его показателя
If Response = vbYes Then
Selection.MoveRight Unit:=wdCharacter, Count:=1, _
Extend:=wdExtend
strTemp = Selection.Text
' Выбираем очередной символ
If strTemp = "," Then
' Это должна быть запятая
Selection.Delete Unit:=wdCharacter, Count:=l
' Удаляем ее
Selection.Font.Reset ' Сбрасываем форматирование
Selection.InsertSymbol Font:="Symbol",
_ CharacterNumber:=-3916, Unicode:=True
' Знак умножения
End If ' Запятую заменили знаком умножения Else
R = MsgBox("***Ошибка: неправильно записан множитель." _
+ Msg, Style, Title) End If
Loop While strTemp = ","
And (Response = vbYes)
Выполняем цикл, пока не обработаем все
множители 1 или не обнаружим ошибку
•
If strTemp = "}" Then
' Список должен заканчиваться закр. скобкой
Selection.Delete Unit:=wdCharacter, Count:=1
' Удаляем скобку
Else
Response = MsgBox("***0шибка: в конце списка нет } ... " _
+ Msg, Style, Title)
If Response = vbYes Then
' Пользователь выбрал Yes (Да)
MyString = "Yes"
' Запомним, что выбрал пользователь
Else ' Пользователь выбрал No (Нет)
MyString = "No"
' Запомним, что выбрал пользователь
End If End If End If End Sub
Function Multiplier() i
' Обработка множителя (и его степени)
Dim strTemp As String
Dim Msg, Style, Title, Help, Ctxt, Response, MyString
Msg = "Хотите продолжить ?"
' Вопрос к пользователю
Style = vbYesNo + vbCritical + vbDefaultButton2' Кнопки
Title = "Очередной множитель: степень простого"
'Заголовок окна
Response = vbYes ' Пока ошибки не обнаружены
' Selection.MoveRight Unit:=wdCharacter, Count:=l,
Extend:=wdExtend strTemp = Selection.Text
' Выбираем очередной символ If strTemp = "{" Then
' Если открывающая скобка - начало множителя
Selection.Delete Unit:=wdCharacter, Count:=1
' Скобку удаляем Selection.MoveRight Unit:=wdWord,
Count:=l, Extend:=wdExtend Selection.MoveRight
Unit:=wdCharacter,
Count:=1 ' Основание Selection.MoveRight Unit:=wdWord,
Count:=1, Extend:=wdExtend strTemp = Selection.Text
' Основание отделяется , от показателя
If strTemp = "," Then
' Разделитель нашли PowExp
' Обрабатываем показатель
Selection.MoveRight Unit:=wdCharacter, Count:=l, _
Extend:=wdExtend
strTemp = Selection.Text
' Этот символ завершает множитель
If strTemp = "}"
Then ' Это должна быть закрывающая скобка
Selection.Delete Unit:=wdCharacter, Count:=1
' удалить ее Else
' Но ведь в конце же должна быть закрывающая скобка
Response = MsgBox("***0шибка в сомножителе: нет } ... " _
+ Msg, Style, Title)
If Response = vbYes Then
' Пользователь выбрал Yes (Да)
MyString = "Yes" ' Запомним, что выбрал пользователь
Else ' Пользователь выбрал No (Нет)
MyString = "No"
' Запомним, что выбрал пользователь
End If End If Else ' Иначе - а где же запятая?
Response = MsgBox("***0шибка в сомножителе: нет , ... " _
+ Msg, Style, Title) If Response = vbYes Then
' Пользователь выбрал Yes (Да)
MyString = "Yes"
'Запомним, что выбрал пользователь
Else ' Пользователь выбрал No (Нет)
MyString = "No" ' Запомним, что выбрал пользователь
End If End If
Else ' Иначе - а где же открывающая скобка ?
Response = MsgBox("***0шибка в сомножителе: нет { ... " _
+ Msg, Style, Title) If Response = vbYes
Then ' Пользователь выбрал Yes (Да)
MyString = "Yes"' Запомним, что выбрал пользователь
Else ' Пользователь выбрал No (Нет)
MyString = "No" ' Запомним, что выбрал пользователь End If
End If
Multiplier = Response
End Function
Sub PowExpO
i
' Обработка пokaзaтeля
t
Dim strTemp As String
Selection.Delete Unit:=wdCharacter, Count:=1
' Удаляем символ Selection.MoveRight Unit:=wdWord,
Count:=l, Extend:=wdExtend strTemp = Selection.Text
' Это и есть показатель If strTemp = "1"
Then ' Если показатель равен 1
Selection.Delete Unit:=wdCharacter, Count:=1
' Удаляем его
Else ' В противном случае форматируем его как надстрочный
With Selection.Font
.Superscript = True 'Надстрочный
End With Selection.MoveRight
Unit:=wdCharacter, Count:=1
Selection.Font.Reset 'Восстановить стиль
End If End Sub
{{3,3}, {5,1}, {7,1}, {13,52},{17,1},{19,551},
{37,1},{73,1},{109,1}, {241,1},{433,1},{38737,1}}
33x5x7xl352xl 7X19S51X37X7 3x109x241x433x38737
Среди чисел вида 2n+1 простые, можно сказать, почти не встречаются, ведь число такого вида может быть простым только тогда, когда n является степенью двойки:
n = 2*. Такие числа называются числами Ферма:
Fn = 22n +1.
Пьер Ферма утверждал, что все такие числа просты. Однако Л. Эйлер установил, что F5= 232+l делится на 641. Давайте попытаемся составить таблицу разложения чисел вида 2"+1 на простые множители. В свое время (70-е годы прошлого столетия) Дональду Кнуту удалось исхитриться и с помощью тождества 2214+1 = (2107-254-Н) (2|07+254-Н) и мощного (для того времени) компьютера факторизовать это число. Давайте попробуем и мы. Вот необходимая программа.
Do[ Print[n,":",FactorInteger[2^n+1]], {n, 214} ]
М254 = 3x56713727820156410577229101238628035243XMi27.
Наряду с разложениями чисел Мерсенна и чисел вида 2n+1, представляет интерес также факторизация чисел вида 2n7-. Так как эти числа будут натуральными только при n > 2, то в программу нужно вставить начальное значение
n, равное 3. Поэтому программа будет иметь следующий вид:
Do[Print[n, ":",Factorlnteger[2^n-7]],{n,3,50}]
До сих пор мы изучали быстродействие функции FactorInteger на аргументах, близких к 2n. В двоичной системе счисления запись таких чисел содержит много нулей или единиц подряд. Число Мерсенна
Mn, например, записывается п единицами, а число 2n+1 — двумя единицами, между которыми стоит л-1 нуль (рассматриваем случай
n > 0). Поэтому может показаться, что функция FactorInteger столь эффективна лишь для чисел, которые имеют специальный вид в двоичной системе счисления. Поэтому давайте изучим возможности этой функции по факторизации больших чисел видов, более случайных с точки зрения теории чисел. Попытаемся разложить, например, числа, десятичная запись которых представляет собой повторение одной и той же цифры л раз. Конечно, если
n =1, то эта цифра повторяется только один раз, и вопрос о разложении решается в уме. С другой стороны, даже если
n> 1, то, разделив такое число на ту цифру, которая повторяется n раз, получим число, десятичная запись которого состоит из л единиц. Так что для факторизации чисел такого вида достаточно иметь таблицу разложения чисел, десятичная запись которых состоит из
n единиц. Обозначим это число через 1n. Как задать такое число? Как легко видеть, число, десятичная запись которого состоит из
n девяток, равно 10n-1. Разделив это число на 9, получим число, десятичная запись которого состоит из л единиц:
(10n-1)/9. Таким образом, мы убедились, что
(10n-1)/9= 1n= 111............................111 («единиц).
Заметим сразу, что такие числа могут быть простыми лишь в том случае, если количество единиц
n в записи такого числа — простое. Действительно, если n = m k, то такое число делится как на число, состоящее из т единиц, так и на число, состоящее из k единиц. Короче говоря, от
m| n => 1m | 1n. (Убедиться в этом очень легко, мысленно выполнив деление "столбиком".)
Теперь несложно написать нужную нам программу.
Do[Print[n,":",FactorInteger[(10^n-1)/9]],{n,70}]
Теперь, следуя логике изучения чисел, близких к 2n, построим таблицу факторизации чисел вида 10n+1. В десятичной системе счисления запись таких чисел начинается и заканчивается единицей, а между этими единицами стоят нули:
10n + 1 = 1000............................00001 (n-1 нулей).
Вспоминая формулы суммы степеней, сразу замечаем, что такие числа могут быть простыми лишь в том случае, если л является степенью двойки, т.е. если
n = 2k. (При нечетных и, все такие числа делятся, например, на сумму оснований, т.е. на 11.)
Вот программа, которая строит нужную нам таблицу.
Do[Print[n,":",Factorlnteger[10^n+1]],{n,70}]
Давайте теперь рассмотрим несколько иной пример. Попытаемся факторизовать числа такой последовательности, которая не может рассматриваться как некоторое тривиальное изменение последовательности аn с целым основанием а. В качестве такой последовательности можем выбрать, например, последовательность Фибоначчи. Напомним, что последовательность Фибоначчи рекуррентно определяется так:
F1 = F2 = 1, Fn+2 = Fn+1 +Fn.
Если Fn — простое, то либо n = 4, либо n — простое. Теперь построим таблицу факторизации чисел Фибоначчи.
Для этого напишем программу, в которой предусмотрим вывод не только разложения числа Фибоначчи, но и самого числа.
Do[Print[n,":",Fibonacci[n]], ":",
FactorInteger[Fibonacci[n]]],{n,270}]
Прочитав заголовок, вы, возможно, скажете: "Раскладывать дроби на простые множители? Да как же это?! Такой операции в арифметике нет!". Действительно, такой операции вроде бы и нет, но вспомните, как часто приходится раскладывать на простые множители числитель и знаменатель одной и той же дроби. И чтобы вы не мучились, по отдельности вызывая функцию
FactorInteger для числителя и знаменателя, можете вызвать ее для всей дроби. Это ведь так удобно! В каком же виде будет представлено разложение? Почти в том же, что и для целых чисел, но только показатели простых множителей знаменателя будут отрицательными. Вот пример:
Factorlnteger[1952/1921]={{2,5},{17,-1},{61,1},{113,-1}}.
Do[Print[n,":",Factorlnteger[BernoulliB[n]]],
{n,2,102,2}]
Sub Factorization()
'Обработка списка множителей
Dim strTemp As String
Dim Msg, Style, Title, Help, Ctxt, Response, MyString
Msg = "Хотите продолжить ?"
' Вопрос
Style = vbYesNo + vbCritical + vbDefaultButton2
'Кнопки
Title = "Разложение на множители"
'Заголовок окна
OptPasteSmartCutPaste = Options.
PasteSmartCutPaste Options.
PasteSmartCutPaste = False
Response = vbYes ' Пока ошибки не обнаружены
Selection.Find.ClearFormatting
' Очистка формата в поле поиска
With Selection.Find
.Text = "{"
' Что ищем - открывающую скобку
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False - .
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForm? = False
End With Selection.Find.Execute
' Находим открывающую фигурную скобку списка
strTemp = Selection.Text
If strTemp = "{" Then
' Если нашли скобку, обрабатываем список
Selection.Delete Unit:=wdCharacter, Count:=1
' Удаляем скобку
Do ' В цикле обрабатываем все элементы списка
Response = Multiplier
' Обработка множителя и его показателя
Selection.MoveRight Unit:=wdCharacter, Count:=1, _
Extend:=wdExtend
strTemp = Selection.Text
' Выбираем очередной символ
If strTemp = ","
Then ' Это должна быть запятая
Selection.Delete Unit:=wdCharacter, Count:=1
' Удаляем ее Selection.Font.Reset
' Сбрасываем форматирование
Selection.InsertSymbol Font:="Symbol", _
CharacterNumber:=-3916, Unicode:=True
' Знак умножения
End If
' Запятую заменили знаком умножения
Loop While strTemp = ","
And (Response = vbYes)
' Выполняем цикл, пока не обработаем все множители
' или не обнаружим ошибку
If strTemp = "}" Then
' Список должен заканчиваться
' закрывающейся скобкой
(Selection.Delete Unit:=wdCharacter, Count:=1
' Удаляем скобку
Else
Response = MsgBox("***0шибка: в конце списка нет } ... " _
+ Msg, Style, Title)
If Response = vbYes Then
' Пользователь выбрал Yes (Да)
MyString = "Yes"
' Запомним, что выбрал пользователь
Else ' Пользователь выбрал No (Нет)
MyString = "No" .
' Запомним, что выбрал пользователь
End If End If End If
Options.PasteSmartCutPaste" = OptPasteSmartCutPaste
End Sub
Function Multiplier() i
' Обработка множителя (и его степени)
1 Макрос записан 26.10.2003 Яков Шмидский t
Dim strTemp As String
Dim Msg, Style, Title, Help, Ctxt, Response, MyString
Msg = "Хотите продолжить ?"
' Вопрос к пользователю
Style = vbYesNo + vbCritical + vbDefaultButton2
' Кнопки
Title = "Очередной множитель: степень простого"
' Заголовок окна
Response = vbYes ' Пока ошибки не обнаружены
strTemp = Selection.Text
' Выбираем очередной символ
Selection.MoveRight Unit:=wdCharacter,
Count:=l, Extend:=wdExtend
If strTemp = "{" Then
' Если отрывающая скобка - начало множителя
Selection.Delete Unit:=wdCharacter, Count:=1
' Скобку удаляем
Selection.Extend Character:=","
' Расширили выделение до ,
Selection.MoveLeft Unit:=wdCharacter, Count:=1,
Extend:=wdExtend
' Отменили выделение , BaseRepresent
Selection.MoveRight Unit:=wdCharacter, Count:=1
' Основание Selection.MoveRight Unit:=wdCharacter,
Count:=l, Extend:=wdExtend strTemp = Selection.Text
' Основание отделяется , от показателя
If strTemp = "," Then
' Разделитель нашли PowExp
' Обрабатываем показатель
Selection.MoveRight Unit:=wdCharacter, Count:=l, _
Extend:=wdExtend
strTemp = Selection.Text
' Этот символ завершает множитель
If strTemp = "}" Then
' Это должна быть закрывающая скобка
Selection.Delete Unit:=wdCharacter, Count:=1
' -Удалить ее Else
' Но ведь в коде же должна быть закрывающая скобка
Response = MsgBox("***0шибка в сомножителе: нет } ... " _
+ Msg, Style, Title) If Response = vbYes Then
' Пользователь выбрал Yes (Да)
MyString = "Yes"
' Запомним, что выбрал пользователь
Else' Пользователь выбрал No (Нет)
MyString = "No"
' Запомним, что выбрал пользователь
End If End If Else ' Иначе - а где же запятая?
Response = MsgBox("***0шибка в сомножителе: нет , ... " _
+ Msg, Style, Title) If Response = vbYes Then
' Пользователь выбрал Yes (Да)
MyString = "Yes"
' Запомним, что выбрал пользователь
Else ' Пользователь выбрал No (Нет)
MyString = "No"
' Запомним, что выбрал пользователь
End If End If End If
Multiplier = Response End Function
Sub PowExp()
t
' Обработка показателя t
Dim strTemp As String
Selection ..Delete Unit :=wdCharacter, Count :=1
' Удаляем символ
Selection.Extend Character:="}"
' Расширили выделение до }
Selection.MoveLeft Unit:=wdCharacter, Count:=1, Extend:=wdExtend
' Отменили выделение }
strTemp = Selection .'Text
' Это и есть показатель
If strTemp = "1" Then
' Если показатель равен 1
Selection.Delete Unit:=wdCharacter, Count:=l
' Удаляем его Else
' В противном случае форматируем его как надстрочный
With Selection.Font
.Superscript = True 'Надстрочный
End With Selection.MoveRight Unit:=wdCharacter, Count:=1
Selection.Font.Reset 'Восстановить стиль
End If End Sub
Sub BaseRepresent() Dim strTemp As String
strTemp = Selection.Text ' Основание
If Not MultiplierQ(strTemp) Then
' Selection.MoveLeft Unit:=wdCharacter, Count:=l '
Selection.InsertBefore "("
' Перед основанием вставим символ {
Selection.InsertAfter ")"
' А после него вставим символ )
End If
End Sub
Function MultiplierQ(strTemp) ret = True
If Left(strTemp, 1) = "-"
Then ret = False MultiplierQ = ret
End Function
{{-1,n},{2,-1},{-3,-m},{5,-1},{7,-1},{11,-1}, {13,-1},{31,-1},
{61,-1},{2003,1},{5549927,8},{109317926249509865753025015237911,1}}
(-1)nх2-1х(-3)-mх5-1х7-1х11-1х13-1х31-1х
61-1x2003x55499278Х109317926249509865753025015237911
Do:[Print[n,":",Factorlnteger[Numerator[BernoulliB[n]]]],{n,2,102,2}].
Напомним, что гауссовыми называются комплексные числа, у которых действительная и мнимая части являются целыми числами. Иными словами, это комплексные числа
а+bi, у которых вещественная (а) и мнимая (b) части представляют собой целые числа. Вот примеры гауссовых чисел:
2, 1+2i, i, -i, 1+i, 1-i, 1+7i, 1+555555i, 9999+444i.
На комплексной плоскости гауссовы числа образуют решетку всех точек с целыми координатами. Гауссовы числа называются в честь К. Ф. Гаусса, который обратил на них внимание еще в 1832 году в работе о биквадратичных вычетах. Именно Гаусс понял важность изучения этих чисел и установил их основные свойства.
Как оказалось, множество гауссовых чисел, рассматриваемое с обычными операциями, образует кольцо, являющееся, конечно, подкольцом кольца (даже поля) комплексных чисел. Кольцо целых гауссовых чисел можно рассматривать как расширение кольца целых чисел Z путем присоединения
i, поэтому это кольцо обозначается Z[i].
В этом кольце делителями единицы являются лишь +1, -1, i и -i. Так что множество делителей единицы в кольце гауссовых чисел конечно. А потому в этом кольце имеет смысл понятие простого элемента, а, значит, можно выполнять разложение элементов этого кольца на простые множители. Нетрудно доказать, что кольцо целых гауссовых чисел евклидово. Поэтому с точностью до делителей единицы разложение на простые множители в нем единственно. Так что кольцо гауссовых чисел (как и всякое евклидово кольцо) является гауссовым, или факториальным.
Нормой комплексного числа называется квадрат модуля, т.е. квадрат длины отрезка, соединяющего комплексное число с началом координат. Иными словами, это сумма квадратов вещественной и мнимой частей комплексного числа:
N(a+bi) = (а+bi)(а-bi) = a2 +b2.
Нечетное простое число р является простым гауссовым числом тогда и только тогда, когда оно дает в остатке 3 при делении на 4: р = 3 (mod 4). Если же р =
3 (mod 4), то р не является простым в кольце целых гауссовых чисел. Не является простым в кольце целых гауссовых чисел и число 2.
Давайте теперь найдем несколько разложений гауссовых чисел на простые множители.
Factorlnteger[5-51]={(-1,1},{1+i,I},{1+2 i,1},{2+i,1}}
FactorInteger[3+1]={{-i,1},(1+i,1},{1+2 1,1)}
FactorInteger[-90-180I]={{1+i,2},{1+2 i,2},{2+i,1},{3,2}}
Factorlnteger[-182-1261]={{1+i,3},{2 + i,3},{7,1}}
FactorInteger[3+I5]={{1+i,1},{4+i,1}}
Factorlnteger[777+1111] ={{-1,1},{1+i,1},{1+6
i,l},{2+i,2},{3,l},{6+i,l}}
Factorlnteger[153+1 374]={{-i,l},{!+4 i,1},{2+i,1},{4+i,1},{8+7
i,l}}
Factorlnteger[7+81]={{7+8i,l}}
Factorlnteger[41,GaussianIntegers->True]={{-1,1},{4+5i,l},{5+4i,lH
FactorInteger[5,GaussianIntegers->True]={{-i,l},{!+2i,i},{2+i,1}}
Factorlnteger[2,GaussianIntegers->True]={{-i,1},{1 + i,2}}
Factorlnteger[11,GaussianIntegers->True]={{11,1}}
FactorInteger[13,GaussianIntegers->True]={{-i,l},{2+3i,l},{3+2
i,l}}
Как мы уже видели, функция Factorlnteger вполне справляется с разложением чисел, десятичная запись которых содержит не более 60—70 десятичных знаков (это примерно две сотни двоичных). Хотя именно такие числа чаще всего встречаются на практике, их множество конечно. Дополнение же этого множества до множества
натуральных чисел бесконечно! Поэтому иногда приходится раскладывать и числа, содержащие несколько сотен, а то и тысяч десятичных знаков. Конечно, в таких случаях зачастую приходится полагаться на удачу. Однако и здесь может помочь Mathematica. Например, если известно, что некоторое число является большой степенью некоторого основания, то достаточно разложить только основание. Так что этот случай большого числа для процедуры факторизации можно считать тривиальным. Несколько менее тривиальным является случай факториала.
Факториалы являются классическим примером больших чисел. В школе, примерно класса с шестого, учителя плавно готовят детей к тому, что факториалы очень быстро растут, а при изучении комбинаторики говорят, что уже 8! = 40320. Тех же, кто этого не устрашится, на школьном кружке пугают тем, что 100! — невообразимо большое число. Такое большое, что даже вычислить его немыслимо. (Но члены школьного математического кружка обычно знают, что это число вычислил Мольтерер еще до появления ЭВМ.) Дня тех же, кто не убоялся этого числа и (зачастую вопреки устрашениям учителей) преодолел конкурсный отбор в вузы, у профессоров есть очередная страшилка: 1000!. Что-то я не видел профессора, который бы выписал десятичную запись этого числа на доске! Наверное, для профессоров оно и вправду страшное! Но не для нас. Мы его (вместе с системой Mathematica) выпишем раньше, чем профессор успеет моргнуть оком.
Действительно, число огромное! Правда, факторизовать его совсем несложно, так как его простые делители известны: даже пятиклассник без труда сообразит, что ими будут все простые числа, меньшие
n = 1000. Что же касается определения показателей, с которыми они входят в каноническое разложение, то здесь положение более сложное. Обычно пятикласснику (участнику городской или районной олимпиады по математике) нужно от пяти до десяти минут на вывод и проверку необходимой формулы. Но ведь Mathematica (точнее, функция
FactorInteger) не проверяет, является ли каждое предлагаемое ей число факториалом некоторого другого числа, и потому применить формулу не сможет! Так сколько же ей понадобится времени на факторизацию этого монстра? На самом деле ответ получается в мгновение ока.
Почему же тогда это разложение получается так быстро? Тому есть две причины. Во-первых, функция Factorlnteger реализует довольно хитрый алгоритм (и к тому же усовершенствованный в версии 5), который умеет пользоваться особенностями числа и ранее найденными множителями. Во-вторых, число имеет малые простые делители, притом в достаточно больших степенях (взгляните на разложение и убедитесь в этом самостоятельно). Поэтому уже в самом начале, как только найден очередной небольшой простой делитель, число делится на его достаточно большую степень, и поиск следующего делителя выполняется для уже значительно меньшего числа. Например, когда найдены все простые делители, меньшие 500, остается факторизовать число
15691 53857 18474 74009 83807 62903 18629
41145 72096 17012 19604 99858
85055 99420 28601 60316 94401 22137 22852
86216 37326 13501 59916 38173
00885 96291 76502 03413 58819 32577 52694 92805
54593 08494 87900 72440 14847 75831
74209 25608 64073 74119.
Давайте на примере попытки разложения больших чисел Мерсенна рассмотрим,
как Mathematica позволяет приблизиться к решению задачи факторизации очень больших чисел.
Факторизация 317-го числа Мерсенна М317
Конечно, можно попытаться применить функцию Factorlnteger. Но это не даст результата (за приемлемое время). Можно, правда, "попросить" функцию Factorlnteger найти хоть какие-нибудь делители числа Мерсенна
М317. Для этого нужно воспользоваться опцией FactorComplete->False.
FactorInteger[M317-1,FactorComplete->False]
Результат будет таким.
FactorInteger::facfn: Unable to factor 28072587476617 «64» 65592773657961.
More...
Чуть ниже будут и найденные множители.
{{9511, 1), {280725874766179960361032187226573
45634038278340298769450465
797600439224658035965592773657961,1}}
Factorlnteger::facfn:
Unable to factor 28072587476617
«64» 65592773657961. More...
{{2807258747661799603610
321872265734563403827834
0298769450465797600439
224658035965592773657961,1}}
m=12
n = Prime[10Am] Prime[10Лт+1]
12 899773470806612917304808883
PrimeQ[9511] True
n=(2Л317-1)/9511
28072587476617996036103218722657345
63403827834029876945046579760043922
4658035965592773657961
PrimeQ[n] False
М317 = 9511X587492521482839879X486812267
1322098041565641X981563923175568
6605031317440031161584572466128599
Factorlnteger[2^337-1,FactorComplete->False]
Factorlnteger::facfn: Unable to factor
57238939242563 «51» 465444456568561. More...
{{18199, 1}, (2806537,1), (95763203297, 1},
{572389392425637497118853974356
80799950268490508661316904465621201465444456568561, 1}}
М337=18199X2806537X95763203297X572389392425637
497118853974356807999502
68490508661316904465621201465444456568561
PrimeQ[18199] True
PrimeQ[2806537] True
PrimeQ[95763203297] True
PrimeQ[5723893924256374971188539743568079
99502684905086613169044656212
01465444456565-61] False
n=57238939242563749711885397435680799950268490
508661316904465621201465
44445656561/726584894969
787780473264667429936124208424161983
11394008068822475527239136925369
PrimeQ[n] True
М337=18199x2806537x95763203297x
726584894969x787780473264667429
93612420 842416198311394008068822475527239136925369
ММ13=2^8191-1
m=FactorIntegerECM[MM13]
338193759479