在Haskell中实现因子分解方法

在Haskell中实现因子分解方法,haskell,factorization,Haskell,Factorization,我在Euler项目中工作,经过一点搜索,找到了快速找到数字因子的方法。你要做的是找到一个数的素因子的所有排列:这些是它的因子 我已经有了一个模块,可以找到一个数字的基本功率因数,例如: Main> primePowerFactors 196 [(2,2),(7,2)] 这基本上表明:2^2*7^2==196。从这里,我想找出这些幂的所有排列,从而给出196的因子: (2^0)(7^0)=1 (2^1)(7^0)=2 (2^2)(7^0)=4 (2^0)(7^1)=7 (2^1)(7^1

我在Euler项目中工作,经过一点搜索,找到了快速找到数字因子的方法。你要做的是找到一个数的素因子的所有排列:这些是它的因子

我已经有了一个模块,可以找到一个数字的基本功率因数,例如:

Main> primePowerFactors 196
[(2,2),(7,2)]
这基本上表明:
2^2*7^2==196
。从这里,我想找出这些幂的所有排列,从而给出196的因子:

  • (2^0)(7^0)=1
  • (2^1)(7^0)=2
  • (2^2)(7^0)=4
  • (2^0)(7^1)=7
  • (2^1)(7^1)=14
  • (2^2)(7^1)=28
  • (2^0)(7^2)=49
  • (2^1)(7^2)=98
我得出了以下结论:

factors n = [a|a<-map facs (primePowerFactors n), y <- [0..(snd $ last $ primePowerFactors n)]]
 where 
  facs (x,y) = (x,y)   
rSq n = toInteger $ round $ sqrt (fromInteger n)    
psr n = last $ dropWhile (<= rSq n) $ factors n
p = foldl' (*) 1 $ takeWhile (< 190) primes
answer = (psr p) `mod` (10^16)

factors n=[a | a首先,
facs
是身份函数:

facs (x,y) = (x,y)
y
绑定在左侧的模式匹配中,而您可能希望它是列表理解中的
y
。列表理解中绑定的变量名是该理解的局部变量,不能在不同的范围内使用,如
where
子句

此外,列表理解中的
y
仅根据最后一个因子指数计算:

y <- [0..(snd $ last $ primePowerFactors n)]
这将返回素数因子幂的列表,同时应生成这些构造的列表,如下所示:

[
   [(2,0), (7,0)],
   [(2,1), (7,0)],
   [(2,2), (7,0)],
   [(2,0), (7,1)],
   [(2,1), (7,1)],
   ...
]

需要对所有可能的因子进行素数分解,但该函数似乎只返回一个素数分解。

对于一些代码,我编写了一个非常简单的幂集函数

powerSet [] = []
powerSet (x:xs) = xs : map (x:) (powerSet xs) ++ (powerSet xs)
这个算法的一个缺陷是它不包含原始集合,但是这对您来说是完美的,因为它看起来不像您想要它

将其与将
primePowerFactors n
转换为整数列表的方法结合起来,比如

ppfToList = concatMap (\(x,y)->replicate y x)
使用这些帮助程序,将生成数字n中的因子列表

factors n = nub . map product . powerSet . ppfToList . primePowerFactors $ n
-- will be out of order, you can add a call to `sort` to fix that

这种算法可能更难用列表理解来表达。

哦,我认为这是个错误,应该是:
facs(x,y)=(x^y)
因此,
factors
返回一个带有更改的
facs的整数列表
您永远不会生成类似
2^1*7^1
的东西,而只生成一个素数的幂的因子。需要更改算法,以生成不同素数因子的组合。如果您想要得到非常大的因子,它会ecomes重要的是,数字的因子是按顺序生成的,否则使用sort将要求它在排序之前将每个因子存储在内存中,然后再给我数字。因为我们知道p有2^42个因子,所以我们想要的因子应该位于已排序因子列表中的索引2^42-1处。实际上,您不需要按顺序排序g到规范。您需要找到低于某个阈值的最大值。这只是
maximum.filter(/=threshold)
,它与优化的常量开销(无论如何都应该是)成线性关系。抱歉
maximum.filter(
factors n = nub . map product . powerSet . ppfToList . primePowerFactors $ n
-- will be out of order, you can add a call to `sort` to fix that