haskell - 检测对角相邻元素

haskell - detect diagonally adjacent elements

函数的objective是以Squares和returnsTrue的list列表的形式取板子如果没有Square 包含一个白色,在下一行中有一个与它对角相邻的绿色方块。

函数签名是:

diagchecker :: [[Square]] -> Bool

正方形定义为:

data Square = White | Green | Empty deriving Eq

例如,diagchecker [[White,Empty],[Empty,Green]] 应该 return False.

diagchecker [[Green,Empty],[Empty,White]] 应该 return True.

diagchecker [[White,Green],[White,White],[Green,Empty]] 应该 return False.

------------更新------------

好的,我基本上离正确完成这一步还差一步。 这是我的代码:

data Square = White | Green | Empty deriving Eq

diagchecker :: [[Square]] -> Bool

anyDiags :: (a -> a -> Bool) -> [[a]] -> Bool
anyDiags p = fst . foldr f (False, [])
  where
    f xs (a, ys) = ( a || or (zipWith p xs (drop 1 ys)) 
                       || or (zipWith p (drop 1 xs) ys)
                   , xs)

greenAfterWhite x y = (x == White && y == Green)
    
diagchecker = anyDiags greenAfterWhite

这段代码确实有效,现在我面临的唯一问题是当白色之后没有绿色时,我希望 diagchecker 到 return True,并且 return False 当有 绿色后白色。在目前的情况下,它正在做检测白色之后是否有绿色的工作,但是结果 Boolean it returns 与我想要的完全相反。谁能帮我解决这个问题?

-----更新2-----

为了改变输出,我试过像这样改变 greenAfterWhite

greenAfterWhite x y 
    | (x == white && y == green) = False
    | otherwise = True

或者这个:

greenAfterWhite x y = not (x == White && y == Green)

对于每个输入 [[Square]].

,这两个更改都会导致 diagchecker returns TRUE

由于您只检查了下面 的两个对角方块,我将其表示为尾巴上的映射。欢迎您根据 foldr:

重新表述
import Data.List (tails)

diagchecker = noGreenUnderWhiteDiagonally

noGreenUnderWhiteDiagonally rows = 
  null [ ()
         | (a:b:_) <- tails rows,
           greenUnderWhite a (drop 1 b) 
           || 
           greenUnderWhite (drop 1 a) b]

greenUnderWhite row1 row2 = 
  or $ zipWith (...) ... ...

如果上面的方块是白色的,您将需要完成定义以检查下方是否存在绿色方块。

or 将检测其参数列表中是否存在任何 True 元素。

代码中已经内置了否定,null 检测其参数列表是否为空。该列表的元素并不重要,因此我们使用“平淡”值 ().

tails 上的映射实现了矩阵中连续行的 成对 比较。