我正在尝试编写一个递归函数,该函数将包含整数列表的列表作为输入并返回类型([Int],Int)的元组。 ([INT],智力)
这是一个“棋盘游戏”,你可以在这里获得一块棋盘:
[[5,4,3,8,6],
[0,2,1,0,7],
[0,1,9,4,3],
[2,3,4,0,9]]
这将是一个包含4行和5列的电路板。列表中的数字是“硬币值”。 这个棋盘游戏的目标是从列表的顶部到收集硬币的底部。您可以从顶行的任何位置开始向下移动,您可以直接向下或向左或向右对角线。您可能希望路径能够为您提供最大的总硬币值。
我已经创建了第一个函数,您输入路径列表[([Int],Int)]并返回具有最大硬币值的路径([Int],Int)。
现在我需要创建一个函数来实际生成我将输入到第一个函数中的路径列表。
我知道我将不得不使用递归。 我将输入电路板(如上图所示)和起始列。 我将不得不取列号,然后创建所有可能路径的列表。 如果我从列号开始,我的下一个可能的步骤是位置(在下一行) - 相同的列号,列号-1和列号+1。我需要递归调用它直到我到达底部。
我如何能够存储这些路径步骤,然后存储所有可能路径的最终列表?
([Int],Int) - [Int]是列表/列号或行中的位置,Int是硬币值。
我是haskell的新手,虽然我明白自己要做什么,但编写代码真的很难。
答案 0 :(得分:1)
您不会在惯用功能代码中的某些变量中“存储”中间值。相反,您将它们保存为累积参数,您可以使用诸如foldr之类的函数传递它。
http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:foldr
答案 1 :(得分:0)
我想我现在能够(轻松)调整我对another question的回答。我列出了允许的索引组合并将其映射到它们。 (pat comment帮助我改进了index_combinations)
*主> :加载“new1.hs”
[1 of 1]编译Main(new1.hs,解释)
好的,加载的模块:Main。
*主>导致
([8,7,4,9],28)
*主>路径
[3,4,3,4]
import Data.List
import Data.Ord
import Data.Maybe
r = [[5,4,3,8,6],
[0,2,1,0,7],
[0,1,9,4,3],
[2,3,4,0,9]]
r1 = r !! 0
r2 = r !! 1
r3 = r !! 2
r4 = r !! 3
index_combinations =
[[a,b,c,d] | a <- [0..4], b <- [max 0 (a-1)..min 4 (a+1)],
c <- [max 0 (b-1)..min 4 (b+1)], d <- [max 0 (c-1)..min 4 (c+1)]]
mapR xs = [r1 !! (xs !! 0), r2 !! (xs !! 1),
r3 !! (xs !! 2), r4 !! (xs !! 3)]
r_combinations = map mapR index_combinations
r_combinations_summed = zip r_combinations $ map (foldr (+) 0) r_combinations
result = maximumBy (comparing snd) r_combinations_summed
path = index_combinations !! fromJust (elemIndex result r_combinations_summed)
答案 2 :(得分:0)
如果您有兴趣使用我的套餐grid (userguide) 这里以一个让你入门的例子。 (如果你不想使用它,你可能会发现一些 源代码很有用。)
创建一个包含4行和5列的网格。
λ> :m + Math.Geometry.Grid
λ> let g = rectSquareGrid 4 5
λ> indices g
[(0,0),(0,1),(0,2),(0,3),(1,0),(1,1),(1,2),(1,3),(2,0),(2,1),(2,2),(2,3),(3,0),(3,1),(3,2),(3,3),(4,0),(4,1),(4,2),(4,3)]
我们希望能够将“硬币值”映射到网格位置,所以我们会 创建一个GridMap。
λ> :m + Math.Geometry.GridMap
λ> let m = lazyGridMap g [5,4,3,8,6,0,2,1,0,7,0,1,9,4,3,2,3,4,0,9]
λ> m
lazyGridMap (rectSquareGrid 4 5) [5,4,3,8,6,0,2,1,0,7,0,1,9,4,3,2,3,4,0,9]
λ> toList m
[((0,0),5),((0,1),4),((0,2),3),((0,3),8),((1,0),6),((1,1),0),((1,2),2),((1,3),1),((2,0),0),((2,1),7),((2,2),0),((2,3),1),((3,0),9),((3,1),4),((3,2),3),((3,3),2),((4,0),3),((4,1),4),((4,2),0),((4,3),9)]
我们可以找到网格中任何单元格的邻居, 但是对于你的应用程序,我们遇到了一个问题:我的 RectSquareGrid类型不允许对角移动。
λ> neighbours (1,2) m
[(0,2),(1,3),(2,2),(1,1)]
现在,我很乐意创建一种符合你的新型Grid
需要。或者,您可以编写自己的函数
其中包括对角线邻居:
λ> let neighbours2 (x, y) g = filter (`inGrid` g) [(x-1,y-1), (x-1,y), (x-1,y+1), (x,y-1), (x,y+1), (x+1,y-1), (x+1,y), (x+1,y+1)]
λ> neighbours2 (1,2) m
[(0,1),(0,2),(0,3),(1,1),(1,3),(2,1),(2,2),(2,3)]
但是你只对允许向下移动(直线向下或对角线)感兴趣,所以这里有一个更有用的功能:
λ> let allowedMoves (x, y) g = filter (`inGrid` g) [(x+1,y-1), (x+1,y), (x+1,y+1)]
λ> allowedMoves (1,2) m
[(2,1),(2,2),(2,3)]
现在我们可以编写一个函数,为您提供从给定索引到网格底行的所有可能路径。
allPathsFrom a g | fst a == fst (size g) = [[a]]
| otherwise = Prelude.map (a:) xs
where xs = concatMap (\x -> allPathsFrom x g) ys
ys = allowedMoves a g
例如:
λ> allPathsFrom (0,1) m
[[(0,1),(1,0),(2,0),(3,0),(4,0)],[(0,1),(1,0),(2,0),(3,0),(4,1)],[(0,1),(1,0),(2,0),(3,1),(4,0)],[(0,1),(1,0),(2,0),(3,1),(4,1)],[(0,1),(1,0),(2,0),(3,1),(4,2)],[(0,1),(1,0),(2,1),(3,0),(4,0)],[(0,1),(1,0),(2,1),(3,0),(4,1)],[(0,1),(1,0),(2,1),(3,1),(4,0)],[(0,1),(1,0),(2,1),(3,1),(4,1)],[(0,1),(1,0),(2,1),(3,1),(4,2)],[(0,1),(1,0),(2,1),(3,2),(4,1)],[(0,1),(1,0),(2,1),(3,2),(4,2)],[(0,1),(1,0),(2,1),(3,2),(4,3)],[(0,1),(1,1),(2,0),(3,0),(4,0)],[(0,1),(1,1),(2,0),(3,0),(4,1)],[(0,1),(1,1),(2,0),(3,1),(4,0)],[(0,1),(1,1),(2,0),(3,1),(4,1)],[(0,1),(1,1),(2,0),(3,1),(4,2)],[(0,1),(1,1),(2,1),(3,0),(4,0)],[(0,1),(1,1),(2,1),(3,0),(4,1)],[(0,1),(1,1),(2,1),(3,1),(4,0)],[(0,1),(1,1),(2,1),(3,1),(4,1)],[(0,1),(1,1),(2,1),(3,1),(4,2)],[(0,1),(1,1),(2,1),(3,2),(4,1)],[(0,1),(1,1),(2,1),(3,2),(4,2)],[(0,1),(1,1),(2,1),(3,2),(4,3)],[(0,1),(1,1),(2,2),(3,1),(4,0)],[(0,1),(1,1),(2,2),(3,1),(4,1)],[(0,1),(1,1),(2,2),(3,1),(4,2)],[(0,1),(1,1),(2,2),(3,2),(4,1)],[(0,1),(1,1),(2,2),(3,2),(4,2)],[(0,1),(1,1),(2,2),(3,2),(4,3)],[(0,1),(1,1),(2,2),(3,3),(4,2)],[(0,1),(1,1),(2,2),(3,3),(4,3)],[(0,1),(1,2),(2,1),(3,0),(4,0)],[(0,1),(1,2),(2,1),(3,0),(4,1)],[(0,1),(1,2),(2,1),(3,1),(4,0)],[(0,1),(1,2),(2,1),(3,1),(4,1)],[(0,1),(1,2),(2,1),(3,1),(4,2)],[(0,1),(1,2),(2,1),(3,2),(4,1)],[(0,1),(1,2),(2,1),(3,2),(4,2)],[(0,1),(1,2),(2,1),(3,2),(4,3)],[(0,1),(1,2),(2,2),(3,1),(4,0)],[(0,1),(1,2),(2,2),(3,1),(4,1)],[(0,1),(1,2),(2,2),(3,1),(4,2)],[(0,1),(1,2),(2,2),(3,2),(4,1)],[(0,1),(1,2),(2,2),(3,2),(4,2)],[(0,1),(1,2),(2,2),(3,2),(4,3)],[(0,1),(1,2),(2,2),(3,3),(4,2)],[(0,1),(1,2),(2,2),(3,3),(4,3)],[(0,1),(1,2),(2,3),(3,2),(4,1)],[(0,1),(1,2),(2,3),(3,2),(4,2)],[(0,1),(1,2),(2,3),(3,2),(4,3)],[(0,1),(1,2),(2,3),(3,3),(4,2)],[(0,1),(1,2),(2,3),(3,3),(4,3)]]
请注意,由于GridMap
也是Grid
,因此我们可以在m
或g
上调用上述所有功能。
λ> allPathsFrom (0,1) m
如果您希望我添加,请告诉我(amy at nualeargais dot ie)
允许对角移动到我的grid
包的网格。