List 在Haskell中创建k-复合数的无限列表

List 在Haskell中创建k-复合数的无限列表,list,function,haskell,List,Function,Haskell,k-复合数是k因子不包括1和自身的复合数。我正在尝试编写一段代码,该代码将接受整数k并返回所有k-composite的无限列表。因此,使用take 5$kcomposite 2将返回[6,8,10,14,15]。为此,我编写了两个函数: factors :: Int -> [Int] factors n = [x | x <- [1..n], n `mod` x == 0] kcomposite :: Int -> [Int] kcomposite n = [x | x &

k-复合数是k因子不包括1和自身的复合数。我正在尝试编写一段代码,该代码将接受整数k并返回所有k-composite的无限列表。因此,使用take 5$kcomposite 2将返回[6,8,10,14,15]。为此,我编写了两个函数:

factors :: Int -> [Int]
factors n = [x | x <- [1..n], n `mod` x == 0]

kcomposite ::  Int -> [Int]
kcomposite n = [x | x <- [1..], (length (factors n)) == (x-2)]
因子::Int->[Int]
因子n=[x | x[Int]
kcomposite n=[x | x
k-复合数是k因子不包括1和自身的复合数

由于
factors
函数返回一个数字的所有因子(包括
1
及其本身),因此该数字将大于提供的
k
。这就是为什么需要与
k+2
进行比较,而不是
k-2

此外,当
k
小于
0
时,程序仍将永不停止运行,这就是您可能希望处理此边缘情况的原因

factors :: Int -> [Int]
factors n = [x | x <- [1..n], n `mod` x == 0]

kcomposite ::  Int -> [Int]
kcomposite k
  | k < 0 = []
  | otherwise = [x | x <- [1..], length (factors x) == (k + 2)]
因子::Int->[Int]
因子n=[x | x[Int]
k组分k
|k<0=[]

|否则=[x | x这是我对这项任务的略微不同的方法,它更有效

增强的关键是不要一直检查到最后,而是只检查到它的平方根。我的意思是,如果我们想找到100的组合,我们不需要控制所有100个数字。我们只需要控制到
sqrt 100
(比如
[2..10]
)就可以看到
(mod 100 x)==0
。我们从2开始,因为你不想要1和数字本身。一旦我们得到了令人满意的数字
100 div x
应该给我们另一个。因此,如果2是一个组合,那么
100 div 2
(50)另一个是4得25分,5得20分。当然,当我们到10分时,它会给我们另外10分,我们只会评估其中一个。酷

这就是代码

kcomposites :: Int -> [Int]
kcomposites k = 
  let factors n = concat [bool [x, n `div` x] [x] (x^2 == n) 
                          | x <- [2..limit], n `mod` x == 0]
          where limit = truncate . sqrt . realToFrac $ n
  in foldr (\n rs -> bool rs (n:rs) (k == (length . factors $ n))) [] [2..]
这是代码在前5个元素的k=19时的性能

*Main> take 5 . kcomposites $ 19
[576,1600,2916,3136,7744]
(0.43 secs, 174,826,272 bytes)
*Main> take 5 . kcomposite $ 19
[576,1600,2916,3136,7744]
(17.61 secs, 6,246,022,504 bytes)
注意:我不建议检查5个元素的k=5。即使是这段代码也需要15分钟才能生成
[64729156251176491771561]
以上代码可能需要花费大量时间(可能需要一天或更长时间)

让我们将它们与
进行比较,取3

*Main> take 3 . kcomposites $ 5
[64,729,15625]
(1.14 secs, 472,228,880 bytes)

*Main> take 3 . kcomposite $ 5
[64,729,15625]
(69.84 secs, 25,409,801,688 bytes)

看起来您切换了x和n。您需要
(长度(因子x))==n-2
。当然还有n+2,而不是n-2…为什么是5?因为7是素数,所以只能通过n^6个数字,即只有一个素数因子的数字来计算。@Ness抱歉……我不确定你的意思……我们要找的5个因子不是素数,而是最大的。当找到一个有9个事实的数字时,有7个因子的数字就足够了除数似乎比5更难找到。作为旁注,一个数要有奇数个因子,它必须有一个完美的整数平方根。如果一个数有素数分解
p^a*q^b*r^c*。
,它的除数总数是
积[a+1,b+1,c+1,…]
,包括1和它自身。因此,如果它有5=7-2个除数,不包括1和它自身,那么它必须是
积[a+1,b+1,c+1,…]=7
,但7是素数,因此该列表中只能有一个条目,
积[a+1]=(a+1)=7
因此
a=6
对于某些素数
p
//对于7个因子,素因式分解是
p^6
/,不包括,它是
积[a+1,b+1,c+1,…]=9
例如
3*3=9
对于
p^2*q^2
,或者
p^8
,9=11-2,11是素数,因子分解是
p^10
。自然,第十次幂比第六次幂稀疏得多。@Will Ness谢谢你的解释。我刚刚有时间来弄清楚你的确切意思。所以找到数字使用
11,15,17,21…(p-2)
因子使用此算法将是困难和浪费的。相反,我们最好将逻辑切换到
take 5。映射(^(k+1))$primes
,因为需要这样数量的因子。酷。。!