2

如果我有 4 个布尔条件,并且我想说如果其中至少 3 个为真,那么做_,这可以在 Haskell 中实现吗?

还是我必须经历每个排列?(即 1.True、2.True、3.True、4.False 和 1.False、2.True、3.True、4.True 等)

谢谢!

4

7 回答 7

5
atleast :: Int -> [Bool] -> Bool
atleast n bools = length tn == n
  where  tn = take n . filter id $ bools

除非我错过了什么,否则应该懒惰地工作。

于 2012-10-08T07:07:38.137 回答
4

如果您希望它在找到 N 个数字后停止检查列表,您可以使用惰性自然数进行计数。

import Data.List
import Data.Number.Natural

atLeast :: Int -> [Bool] -> Bool
atLeast n = (>= (fromIntegral n :: Natural)) . genericLength . filter id
于 2012-10-08T06:42:12.677 回答
4

该解决方案与目前提供的其他解决方案的不同之处在于它短路(即,在找到n Bools 后停止)。所以它可以在一些无限列表上运行(只有那些最终会评估为True的列表),并且不一定会强制评估列表中的每个元素(由于懒惰)。

atLeast :: Int -> [Bool] -> Bool
atLeast 0 _          = True
atLeast _ []         = False
atLeast n (True:bs)  = atLeast (n - 1) bs
atLeast n (False:bs) = atLeast n bs
于 2012-10-08T06:19:26.530 回答
4

每个排列?当然不是..您可以计算为真的条件的数量。

于 2012-10-08T00:47:46.500 回答
2

这不是最美丽的方式,但你可能会发现

atLeast :: Int -> [Bool] -> Bool
atLeast n bools = length (filter (==True) bools) >= n

最容易理解。filter只保留清单中满足你给它的规则的东西。在这种情况下,规则是答案必须是True。接下来,length计算剩下多少。

(规则是一个函数a -> Bool,其中a是列表中元素的类型)。

于 2012-10-08T02:14:22.283 回答
2
atLeast3 :: Bool -> Bool -> Bool -> Bool -> Bool
atLeast3 b1 b2 b3 b4 = sum (map fromEnum [b1, b2, b3, b4]) >= 3
于 2012-10-08T02:01:50.773 回答
1
requireAtLeast :: Int -> [Bool] -> Bool
requireAtLeast n = (>= n) . length . filter id

如果您更喜欢极端有意义或无意义的形式,它们分别是:

requireAtLeast threshold predicates = length (filter (\predicate -> predicate) predicates) >= threshold

requireAtLeast = (. length . filter id) . (<=)
于 2012-10-08T01:33:31.963 回答