Да, по другим модулям я квадраты не проверял, только по 8. Пока думаю как это покомпактнее и не слишком тормознуто записать в программе генерации паттернов.
Легко может оказаться что квадраты
в каждом паттерне окажутся недопустимыми, не знаю, надо смотреть.
То что числа большие не слишком страшно, если много чисел проверяемы (т.е. имеют форму
или
), то ispseudoprime справится, а факторизировать придётся лишь
реальные кандидаты на решение, коих
мало и можно хоть часы ждать каждого (в отдельном потоке), да к тому же если это и правда решение, то факторизация срабатывает быстро, можно ещё и так ограничить. А можно попытаться и все числа сделать проверяемыми (Вы же сами именно так и поступили с M(30)=4 и M(30)=5). Числа будут огромными, да, но мы ведь ищем не минимальные решения, нам ведь подойдут любые, главное чтобы нашлись. И мне не кажется очевидным что перебирая линейно вероятность наткнуться на правильное непроверяемое
столь уж сильно выше чем перебирая простое под квадратом наткнуться на правильное проверяемое
, которое причём гарантированно делится на
(и для проверки не надо делать факторизацию, достаточно проверки на простоту). Т.е. она да, выше, но не на порядки, вот написал простенький тест и запустил для 20,30,40,50-значных чисел:
Код:
? a=vector(20); for(i=0,10^4, t=factor(12345678901234567890+i)[,2]; if(vecmax(t)>1, next); a[#t]++); print(a)
[206, 942, 1579, 1612, 1063, 485, 160, 25, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
time = 2,090 ms.
? a=vector(20); for(i=0,10^4, t=factor(123456789012345678901234567890+i)[,2]; if(vecmax(t)>1, next); a[#t]++); print(a)
[142, 662, 1337, 1535, 1281, 731, 278, 91, 21, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
time = 11,139 ms.
? a=vector(20); for(i=0,10^4, t=factor(1234567890123456789012345678901234567890+i)[,2]; if(vecmax(t)>1, next); a[#t]++); print(a)
[110, 583, 1094, 1480, 1260, 922, 405, 160, 46, 15, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
time = 1min, 6,692 ms.
? a=vector(20); for(i=0,10^4, t=factor(12345678901234567890123456789012345678901234567890+i)[,2]; if(vecmax(t)>1, next); a[#t]++); print(a)
[94, 428, 1053, 1347, 1331, 985, 543, 207, 73, 21, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0]
time = 11min, 46,295 ms.
Простые заметно реже произведения двух простых, но произведения трёх простых ещё чаще, а четырёх и ещё.
Конечно 40 цифр это не 70 и не 150, но и разница не на порядки, а лишь в разы, и отношение a[2]/a[1] более-менее сохраняется.