如何让我的函数同时在两个列表中移动?
How to make my function move through two lists at once?
我正在尝试制作一个函数,它将 Int
s 的列表列表作为输入,并在每次将 运行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的合作中.
我正在尝试制作一个函数,它将 Int
s 的列表列表作为输入,并在每次将 运行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的合作中.