I may do it using the factors
function, or otherwise.
I recommend doing it otherwise.
One simple way is to implement a function getting the prime factorization of a number, and then you can have
isHamming :: Integer -> Bool
isHamming n = all (< 7) $ primeFactors n
which would then be used to filter the list of all positive integers:
hammingNumbers :: [Integer]
hammingNumbers = filter isHamming [1 .. ]
Another way, more efficient is to avoid the divisions and the filtering, and create a list of only the Hamming numbers.
One simple way is to use the fact that a number n
is a Hamming number if and only if
n == 1
, or
n == 2*k
, where k
is a Hamming number, or
n == 3*k
, where k
is a Hamming number, or
n == 5*k
, where k
is a Hamming number.
Then you can create the list of all Hamming numbers as
hammingNumbers :: [Integer]
hammingNumbers = 1 : mergeUnique (map (2*) hammingNumbers)
(mergeUnique (map (3*) hammingNumbers)
(map (5*) hammingNumbers))
where mergeUnique
merges two sorted lists together, removing duplicates.
That’s already rather efficient, but it can be improved by avoiding producing duplicates from the beginning.