Камрады, очередное ускорение, теперь в 20+ раз!

Рассмотрим приведённый ранее код, реализующий часть функционала factor(n+d,2^14):
foreach(z16,d, nf=0; x=n+d; forprime(p=67,2^14, if(x%p==0, nf++; x=x\p); ); if(nf>4, next(2) , nf==4 && !ispseudoprime(x), next(2) , nf<4 && ispseudoprime(x), next(2)); )На уровне идеи тут каждое из чисел n+d, приму что d=[0..21], проверяется не делится ли оно на простые 67...2^14.
Отдельно замечу что вычислять x=(n+d)/v[d+1] до использования в ispseudoprime (куда выполнение может и не дойти) нет необходимости, это тоже экономит часть длинных делений.
Но эту проверку можно сделать и по другому:
forprime(p=67,2^14, d=(n+21)%p; if(d>=21, next); ... )Т.е. просто посчитать остаток от деления последнего числа на простое и если он меньше 21, то одно из чисел, а именно 21-d, разделилось на p. Далее можно уже его проверять как хочется.
Больше одного числа разделиться не может, так как min(p)>21.
В итоге не надо делать 22 деления на каждое простое, достаточно одного.
Да, код проверки будет сложнее, nf заменится на nf[] длиной 22, вместо z16[] нужен nu[] (требуемое количество делителей, которое omega), но думаю оно стоит.
-- 02.12.2025, 16:59 --Понятно что 20 раз от factor(n,2^14) не получится, но какое-то должно быть, и не совсем малое.
А уж если скомпилить, да ещё и поправить переменные в цикле, там ведь лишь одна длинная, n+21, то будет ещё побыстрее.