简体   繁体   English

Haskell 遍历列表列表中的每个 2x2 网格并应用 function

[英]Haskell iterate through each 2x2 grid over a list of list and apply function

suppose I have a list of list xs .假设我有一个 list xs列表。 Each element in xs has the same length (eg xs is not like [[1,2],[1],[1,2,3]] ). xs中的每个元素都具有相同的长度(例如xs不像[[1,2],[1],[1,2,3]] )。 And I have a function f , which return a Bool .我有一个 function f ,它返回一个Bool I want to apply f to each of the 2x2 grid in xs and get the AND result of the applications.我想将f应用于xs中的每个 2x2 网格并获得应用程序的AND结果。

For example,例如,

xs = [[1,2,3],[4,5,6],[7,8,9]]

f :: [[Int]] -> Bool
f [[1,_][_,_]] = False
f _ = True ​

In this case, I want to在这种情况下,我想

  • apply f to [[1,2],[4,5]] and return Falsef应用于[[1,2],[4,5]]并返回False
  • apply f to [[2,3],[5,6]] and return Truef应用于[[2,3],[5,6]]并返回True
  • apply f to [[4,5],[7,8]] and return Truef应用于[[4,5],[7,8]]并返回True
  • apply f to [[5,6],[8,9]] and return Truef应用于[[5,6],[8,9]]并返回True

Then the final result should be False as 3 Trues and 1 False result in False.那么最终结果应该是False ,因为 3 True 和 1 False 导致 False。

Currently I write a function that help me to extract a 2x2 grid from the list目前我写了一个 function 帮助我从列表中提取一个 2x2 网格

get_grid :: [[Int]] -> [[Int]]
get_grid xs = map (take 2) (take 2 xs)

Is there any way to iterate over xs by get_grid and apply f in each iteration and AND the result?有没有办法通过get_grid迭代xs并在每次迭代中应用f得出结果?

Thanks for any help.谢谢你的帮助。

If you write a function to get all adjacent pairs from a list:如果您编写 function 以从列表中获取所有相邻对:

pairs :: [a] -> [[a]]
pairs (x:y:rest) = [x,y] : pairs (y:rest)
pairs _ = []

you can apply it to your matrix to get the submatrices consistent of adjacent pairs of rows:您可以将其应用于矩阵以获得相邻行对的子矩阵:

> pairs xs
[[[1,2,3],[4,5,6]],[[4,5,6],[7,8,9]]]

Transpose each of these submatrices:转置这些子矩阵中的每一个:

> map transpose . pairs $ xs
[[[1,4],[2,5],[3,6]],[[4,7],[5,8],[6,9]]]

and then split them into submatrices of pairs of rows, as before:然后将它们拆分为成对行的子矩阵,如前所述:

> concatMap pairs . map transpose . pairs $ xs
[[[1,4],[2,5]],[[2,5],[3,6]],[[4,7],[5,8]],[[5,8],[6,9]]]

and transpose them back:并将它们转回:

> map transpose . concatMap pairs . map transpose . pairs $ xs
[[[1,2],[4,5]],[[2,3],[5,6]],[[4,5],[7,8]],[[5,6],[8,9]]]

Those are the matrices you wanted, and you can check that f is true for all of them with:这些是您想要的矩阵,您可以通过以下方式检查f是否适用于所有矩阵:

> all f . map transpose . concatMap pairs . map transpose . pairs $ xs
False

A full example:一个完整的例子:

import Data.List

pairs :: [a] -> [[a]]
pairs (x:y:rest) = [x,y] : pairs (y:rest)
pairs _ = []

f :: [[Integer]] -> Bool
f [[1,_],[_,_]] = False
f _ = True

xs :: [[Integer]]
xs = [[1,2,3],[4,5,6],[7,8,9]]

ys :: [[Integer]]
ys = [[0,2,3],[4,5,6],[7,8,9]]

check_grid :: ([[a]] -> Bool) -> [[a]] -> Bool
check_grid f = all f . map transpose . concatMap pairs . map transpose . pairs

main = do
  print $ check_grid f xs
  print $ check_grid f ys

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM