Хорошо, реальный вопрос здесь заключается в следующем: вы выполняете поиск среди списка [0..]
последнего значения m
, для которого p^m
делит n
. В настоящее время вы выполняете поиск по порядку, линейно увеличивая список. Есть ли лучший поиск?
Не знаю наверняка, но, возможно, вы можете добиться большего успеха, быстрее прыгая вперед, пока не получите верхнюю и нижнюю границы на m
. Например, одним из способов было бы угадать верхнюю границу (скажем, 1
), а затем многократно удваивать ее, пока она действительно не станет верхней границей; алгоритм выглядит очень похоже на повторное возведение в квадрат:
upBound p n = if n `mod` p == 0 then 2 * upBound (p^2) n else 1
divs p n = m + divs' p (n `div` (p ^ m)) where
m = upBound p n `div` 2
divs' p n = {- your algorithm -}
Вы можете представить несколько других поисковых стратегий, если вопрос сформулирован в этой форме, но эта простая и должна быть примерно в два раза быстрее, если вы ожидаете, что большие значения m
будут общими.
edit: упс, похоже, что я отвечал "есть ли способ написать это быстрее", а не "есть ли способ написать это короче"