haskell 中的匹配数字序列
Matching Number sequences in haskell
我的任务是匹配 Haskell 中列表中数字 5,7 和 9 的数字序列。该列表必须是无限的,因此以下情况是可能的:
取10个序列
[5,7,9,10,14,15,18,20,21,25]
我已经想出了如何创建单个数字的无限序列列表:
sevens :: [Int]
sevens = sevens : (map (+7) sevens)
这行得通,但我该如何处理多个数字(在本例中为 5,7 和 9)?
感谢您的帮助:)
知道了..差不多了
seq :: [Int]->[Int]
seq (x:xs) if (mod x 5 == 0 || mod x 7 == 0 || mod x 9 == 0) then (x: seq xs)
else (seq xs)
但您仍然必须输入自然数列表才能工作。可以不输入吗?
这个怎么样
multiples_of_any_of :: [Int] -> [Int]
multiples_of_any_of base = filter (\x -> any (\b -> 0 == mod x b) base ) [1..]
answer::[Int]
answer = multiples_of_any_of [5,7,9]
我将 main 函数保留为一般形式,因此它可用于获取数字倍数的任意组合,而不仅仅是 [5,7,9]
,并且作为其定义的一部分,它包括了自然数的供应[1..]
的形式。最后答案就如上图一样简单
例子
*Main> take 30 answer
[5,7,9,10,14,15,18,20,21,25,27,28,30,35,36,40,42,45,49,50,54,55,56,60,63,65,70,72,75,77]
(0.00 secs, 0 bytes)
*Main>
*Main> take 10 (multiples_of_any_of [5,13,23])
[5,10,13,15,20,23,25,26,30,35]
(0.00 secs, 933980 bytes)
*Main>
以前的答案要好得多,但这里有一个 brute-force 方法符合您的思路。
merge :: [[Integer]] -> [Integer]
merge all@[(a:as), (b:bs), (c:cs)] = let min = minimum [a, b, c]
in min : (merge (map (dropMin min) all))
where dropMin m (x:xs)
| x == m = xs
| otherwise = (x:xs)
> take 15 $ merge [[5, 10 .. ], [7, 14 ..], [9, 18 ..]]
[5,7,9,10,14,15,18,20,21,25,27,28,30,35,36]
我的任务是匹配 Haskell 中列表中数字 5,7 和 9 的数字序列。该列表必须是无限的,因此以下情况是可能的:
取10个序列 [5,7,9,10,14,15,18,20,21,25]
我已经想出了如何创建单个数字的无限序列列表:
sevens :: [Int]
sevens = sevens : (map (+7) sevens)
这行得通,但我该如何处理多个数字(在本例中为 5,7 和 9)?
感谢您的帮助:)
知道了..差不多了
seq :: [Int]->[Int]
seq (x:xs) if (mod x 5 == 0 || mod x 7 == 0 || mod x 9 == 0) then (x: seq xs)
else (seq xs)
但您仍然必须输入自然数列表才能工作。可以不输入吗?
这个怎么样
multiples_of_any_of :: [Int] -> [Int]
multiples_of_any_of base = filter (\x -> any (\b -> 0 == mod x b) base ) [1..]
answer::[Int]
answer = multiples_of_any_of [5,7,9]
我将 main 函数保留为一般形式,因此它可用于获取数字倍数的任意组合,而不仅仅是 [5,7,9]
,并且作为其定义的一部分,它包括了自然数的供应[1..]
的形式。最后答案就如上图一样简单
例子
*Main> take 30 answer
[5,7,9,10,14,15,18,20,21,25,27,28,30,35,36,40,42,45,49,50,54,55,56,60,63,65,70,72,75,77]
(0.00 secs, 0 bytes)
*Main>
*Main> take 10 (multiples_of_any_of [5,13,23])
[5,10,13,15,20,23,25,26,30,35]
(0.00 secs, 933980 bytes)
*Main>
以前的答案要好得多,但这里有一个 brute-force 方法符合您的思路。
merge :: [[Integer]] -> [Integer]
merge all@[(a:as), (b:bs), (c:cs)] = let min = minimum [a, b, c]
in min : (merge (map (dropMin min) all))
where dropMin m (x:xs)
| x == m = xs
| otherwise = (x:xs)
> take 15 $ merge [[5, 10 .. ], [7, 14 ..], [9, 18 ..]]
[5,7,9,10,14,15,18,20,21,25,27,28,30,35,36]