【问题标题】:How can I check which list has the least copies of one element?如何检查哪个列表中一个元素的副本最少?
【发布时间】:2021-05-05 14:54:01
【问题描述】:

我正在用 Haskell 写一个数独谜题,我有一个 [[Maybe Int]] 我需要检查哪个 [Maybe Int] 包含最少的 Nothing 元素。换句话说,在下面的代码中我应该返回 1,也就是只有两个 Nothing 的列表的位置:

newtype Puzzle = Puzzle [[Maybe Int]]


deriving (Show, Eq) 
    example :: Puzzle
    example =    [ [Just 3, Just 6, Nothing,Nothing,Just 7, Just 1, Just 2, Nothing,Nothing]
                 , [Just 7,Just 5, Just 4, Just 9, Just 4, Nothing, Just 1, Just 8, Just 2]
                 , [Nothing,Nothing,Just 9, Just 2, Nothing,Just 4, Just 7, Nothing,Nothing]
                 , [Nothing,Nothing,Nothing,Nothing,Just 1, Just 3, Nothing,Just 2, Just 8]
                 , [Just 4, Nothing,Nothing,Just 5, Nothing,Just 2, Nothing,Nothing,Just 9]
                 , [Just 2, Just 7, Nothing,Just 4, Just 6, Nothing,Nothing,Nothing,Nothing]
                 , [Nothing,Nothing,Just 5, Just 3, Nothing,Just 8, Just 9, Nothing,Nothing]
                 , [Nothing,Just 8, Just 3, Nothing,Nothing,Nothing,Nothing,Just 6, Nothing]
                 , [Nothing,Nothing,Just 7, Just 6, Just 9, Nothing,Nothing,Just 4, Just 3]
                 ]

[编辑]

我已经想出了一个解决方案,可以满足我的要求,但这非常缓慢且效率低下,所以我想知道是否有任何方法可以以算法更快的方式编写它。

nrOfBlanks :: Puzzle -> [Int]
nrOfBlanks sud = map length [ filter isNothing r | r <- rows sud] 

whichBlock :: Puzzle -> Maybe Int
whichBlock sud = 
whichBlock sud = let i = nrOfBlanks sud 
                  in head(map (\x -> case x of
                              0 -> elemIndex (foldl1' min (tail i)) i
                               _ -> elemIndex (foldl1' min i) i) i)

有什么帮助吗?提前致谢!

【问题讨论】:

  • 你尝试了什么?什么不工作?
  • 尝试组合使用countNothing = length . filter isNothingminimumByindexed = zipWith [0..],当然还有fst
  • @WillemVanOnsem 我编辑了,所以你可以看到我到目前为止的内容

标签: list haskell functional-programming maybe


【解决方案1】:

所以你想根据一些度量找到最小元素的(索引)——在你的例子中Nothing元素的数量,但显然这是一个更一般概念的特例:您有一些函数a -&gt; Int 可用于[a] 列表的元素。换句话说,您需要一个具有类似签名的助手

minIndexAccordingTo :: (a -> Int) -> [a] -> Int

minimumAccordingTo :: (a -> Int) -> [a] -> a

向 Hoogle 询问此类问题总是一个好主意。 The first one doesn't give useful results,但the second 给出了前两个建议

maximumOn :: (Partial, Ord b) => (a -> b) -> [a] -> a
minimumOn :: (Partial, Ord b) => (a -> b) -> [a] -> a

所以,minimumOn 几乎正是您所需要的。可以导入from the extra package,或者这里定义只使用base

import Data.List (sortOn)

minimumOn :: Ord b => (a -> b) -> [a] -> a
minimumOn f = head . sortOn f

请注意,即使排序是 O (n · log n),由于惰性,这个定义在线性时间内有效。 p>

现在,要使用它来查找 索引,您首先需要将元素与索引配对,相应地更改指标,然后在最后丢弃原始值:

minimumIndexOn :: Ord b => (a -> b) -> [a] -> Int
minimumIndexOn f = fst . minimumOn (f . snd) . zip [0..]

【讨论】:

    猜你喜欢
    • 2011-05-04
    • 1970-01-01
    • 1970-01-01
    • 2018-05-13
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 2021-08-24
    • 2011-03-31
    相关资源
    最近更新 更多