如何让我的函数同时在两个列表中移动?

How to make my function move through two lists at once?

我正在尝试制作一个函数,它将 Ints 的列表列表作为输入,并在每次将 运行s 变成更大或等于的数字时加 +1到 10。我在每一边都添加了 -20,所以 xc 可以从 0 开始。 例如函数 运行s 进入第一个 '10' 后应该发生什么:

     [[-20,-20, 0, 0, 0, 0, 0, 0, 0,-20,-20],
      [-20,-20, 0,10, 1, 0, 0, 0, 0,-20,-20],
      [-20,-20, 1, 1, 1, 0,10, 0, 0,-20,-20],
      [-20,-20, 0, 0, 0,10, 0, 0, 0,-20,-20],
      [-20,-20, 0, 0, 0, 0, 0, 0,10,-20,-20],
      [-20,-20,10,10,10, 0, 0, 0, 0,-20,-20],
      [-20,-20,10, 0,10, 0, 0, 0, 0,-20,-20],
      [-20,-20,10,10,10, 0, 0, 0, 0,-20,-20]]

SampleInput = [[-20,-20, 0, 0, 0, 0, 0, 0, 0,-20,-20],
               [-20,-20, 0,10, 0, 0, 0, 0, 0,-20,-20],
               [-20,-20, 0, 0, 0, 0,10, 0, 0,-20,-20],
               [-20,-20, 0, 0, 0,10, 0, 0, 0,-20,-20],
               [-20,-20, 0, 0, 0, 0, 0, 0,10,-20,-20],
               [-20,-20,10,10,10, 0, 0, 0, 0,-20,-20],
               [-20,-20,10, 0,10, 0, 0, 0, 0,-20,-20],
               [-20,-20,10,10,10, 0, 0, 0, 0,-20,-20]]

adder::[[Int]] -> [[Int]]
adder ((xa:xb:xc:xd:xe):(ya:yb:yc:yd:ye)) 
    | xc >= 10  = adder ((xb:xc:(xd+1):xe):((yb+1):(yc+1):(yd+1):ye))
    | otherwise = adder ((xb:xc:xd:xe):(yb:yc:yd:ye)) 

我也不知道如何应用 xa : adder...如果它是一个列表,我们可以很容易地做到这一点。任何想法如何修复此代码? 此外,如果需要,您可以将 -20 替换为最多 10,这只是为了定位,因为我计划在将函数应用于列表后删除这些 -20。

我想 运行 在反向列表上第二次运行,如果你想象一下扫雷器,其中 10 是地雷,你就会明白为什么

我认为这很容易,只要数据结构保持[[Int]]。请参阅以下示例:

addIf10 :: Int -> Int
addIf10 x = if x >= 10 then x + 1 else x

-- The first map "unpacks" the list to form an [Int]
-- Second map runs the addIf10 function on the [Int]
adder :: [[Int]] -> [[Int]]
adder = map (map addIf10)

我知道你是怎么想到这个主意的。从某种意义上说,你正在创造一个巨大的模式并移动它 沿着雷区。它可以工作。但这不是一个简单的方法。

adder :: [[Int]] -> [[Int]]
adder [ ] = [ ]
adder [x] = [x]
adder t@[  [_, _],   [_, _]    ] = t
adder   (u@[_, _]: v@[_, _]: us) = u: v: adder us
adder t = afterPass !! 0: adder (afterPass !! 1: us)
  where
    t' = applyHalfStencil t

    (  (x: xs)
     : (y: ys)
     : us
     ) = t'

    xys = [xs, ys]

    afterPass = [x: adder xys !! 0, y: adder xys !! 1]

applyHalfStencil
      s@( (xa: xb: xc: xs)
        : (ya: yb: yc: ys)
        : us
        )
    | xb > 9 =
        ( (xa    : xb    : xc + 1: xs)
        : (ya + 1: yb + 1: yc + 1: ys)
        : us
        )
    | otherwise = s

当然,您还必须在字段的上方和下方填充 -20。顺便说一下,一层 -20 就够了。示例:

sampleInput :: [[Int]]
sampleInput = [ [-20 , -20 , -20 , -20 , -20 , -20]
              , [-20 , 10  , 0   , 0   , 0   , -20]
              , [-20 , 0   , 10  , 10  , 10  , -20]
              , [-20 , 0   , 10  , 0   , 10  , -20]
              , [-20 , 0   , 10  , 10  , 10  , -20]
              , [-20 , -20 , -20 , -20 , -20 , -20] ]

当我们这样做的时候,没有什么能阻止我们一次应用整个模板,而不仅仅是较低的模板 右半部分。

adder :: [[Int]] -> [[Int]]
adder [ ] = [ ]
adder [x] = [x]
adder [x, y] = [x, y]
adder t@[  [_, _], _, _    ] = t
adder   (u@[_, _]: v: w: us) = u: v: w: adder us
adder t = afterPass !! 0: adder (afterPass !! 1: afterPass !! 2: us)
  where
    t' = applyStencil t

    (  (x: xs)
     : (y: ys)
     : (z: zs)
     : us
     ) = t'

    xyzs = [xs, ys, zs]

    afterPass = [x: adder xyzs !! 0, y: adder xyzs !! 1, z: adder xyzs !! 2]

applyStencil
      s@( (xa: xb: xc: xs)
        : (ya: yb: yc: ys)
        : (za: zb: zc: zs)
        : us
        )
    | yb > 9 =
        ( (xa + 1: xb + 1: xc + 1: xs)
        : (ya + 1: yb    : yc + 1: ys)
        : (za + 1: zb + 1: zc + 1: zs)
        : us
        )
    | otherwise = s

所以,我们来了,另一种解决方案。它可能更有效率。你把它也很好 创造性的力量进入问题。


未来reader,对于上下文:这个问题和答案继续查询行开始 在我们之前与Jakub的合作中.