Вот версия, которая всегда производит отсортированные результаты, удаляет дубликаты, создает бесконечный список (из которого вы можете take
), и является относительно эффективной (должна иметь постоянную память!):
multiples :: (Num a, Ord a) => [a] -> [a]
multiples = map (fst.head) . iterate step . prep
where prep = map (\i -> (i,i))
next (m,i) = (m+i,i)
step (p:ps) = uniq $ insert (next p) ps
insert q [] = [q]
insert q (p:ps) | q > p = p : insert q ps
insert q ps = q : ps
uniq p@((ma,_):(mb,_):_) | ma == mb = step p
uniq p = p
Пример:
> take 20 $ multiples [4,9]
[4,8,9,12,16,18,20,24,27,28,32,36,40,44,45,48,52,54,56,60]
> take 20 $ multiples [4,8,10]
[4,8,10,12,16,20,24,28,30,32,36,40,44,48,50,52,56,60,64,68]
> take 20 $ multiples [4, 9, 20]
[4,8,9,12,16,18,20,24,27,28,32,36,40,44,45,48,52,54,56,60]
Примечание: предполагается, что список ввода отсортирован. Добавьте . sort
после . prep
, чтобы удалить это ограничение.