Нужен быстрый алгоритм

Я бы хотел сравнить различные тесты простоты на скорость. Я хочу реализовать тест по теореме Вильсона. Мне нужно реализовать вычисление (p - 1)! mod p Но на мое удивление различные алгоритмы, хорошо себя показывающие при вычислении факториала, оказываются бесполезны, они проигрывают классическому вычислению через n! mod p = (n * (n - 1)!) mod p. Подскажите эффективные алгоритмы вычисления n! по простому модулю p>n, либо для данного частного случая. Я для вычисления n! без модуля использую алгоритм PrimeSwing, обгоняющий даже math.factorial, но я не думал над его версией для вычислений по модулю.

def factpow1(n, k):
    res = 0
    while n:
        n = n // k
        res += n % 2
    return res
def SwingingFactorial(n):
    t = 1
    for i in primes(n):
        t = (t * i ** factpow1(n, i))
    return t
def PrimeSwing(n):
    if n < 500:
        return factorial(n)
    else:
        return SwingingFactorial(n) * PrimeSwing(n // 2) ** 2

Ответы (0 шт):