我需要定义唯一素数因子为2,3和5的汉明数字列表。 (即2 ^ i * 3 ^ j * 5 ^ k形式的数字。序列以1,2,3,4,5,6,8,9,10,12,15 ......开头)
我可以使用factors
函数或其他方式执行此操作。下面的factors
应该返回其参数的因子。我相信我已经正确实施了它。
factors :: Int -> [Int]
factors n = [x | x <- [1..(div n 2) ++ n], mod n x == 0]
我尝试使用列表推导制作2 ^ i * 3 ^ j * 5 ^ k的列表,但却一直坚持写守卫:
hamming :: [Int]
hamming = [n | n <- [1..], „where n is a member of helper“]
helper :: [Int]
helper = [2^i * 3^j * 5^k | i <- [0..], j <- [0..], k <- [0..]]
答案 0 :(得分:11)
我可以使用
factors
函数或其他方式来完成。
我建议不这样做。
一种简单的方法是实现一个获得数字素数因子化的函数,然后就可以了
isHamming :: Integer -> Bool
isHamming n = all (< 7) $ primeFactors n
然后将用于过滤所有正整数的列表:
hammingNumbers :: [Integer]
hammingNumbers = filter isHamming [1 .. ]
另一种方法,更有效的是避免划分和过滤,并创建仅汉明数字的列表。
一种简单的方法是使用一个数字n
是汉明数的事实,当且仅当
n == 1
或n == 2*k
,其中k
是汉明号,或n == 3*k
,其中k
是汉明号,或n == 5*k
,其中k
是汉明号。然后您可以创建所有汉明号码列表
hammingNumbers :: [Integer]
hammingNumbers = 1 : mergeUnique (map (2*) hammingNumbers)
(mergeUnique (map (3*) hammingNumbers)
(map (5*) hammingNumbers))
其中mergeUnique
将两个已排序的列表合并在一起,删除重复项。
这已经相当有效了,但是it can be improved by avoiding producing duplicates from the beginning。
答案 1 :(得分:2)
请注意,hamming
设置为
{2^i*3^j*5^k | (i, j, k) ∈ T}
,其中
T = {(i, j, k) | i ∈ [0..], j ∈ [0..], k ∈ [0..]}
但我们不能使用[(i,j,k)| i&lt; - [0 ..],j&lt; - [0 ..],k&lt; - [0 ..]]。因为此列表以无限多个三元组开头,例如(0, 0, k)
鉴于任何(i,j,k)
,elem (i,j,k) T
应在有限时间内返回True
听起来很熟悉?您可以回想一下之前提出的问题:
haskell infinite list of incrementing pairs
在那个问题上,哈马尔给了答案。我们可以把它推广到三倍。
triples = [(i,j,t-i-j)| t <- [0..], i <- [0..t], j <- [0..t-i]]
hamming = [2^i*3^j*5^k | (i,j,k) <- triples]