Haskell回溯跟踪递归

时间:2014-08-07 03:50:27

标签: list haskell recursion maze

我在haskell中实现这个。

https://www.cs.bu.edu/teaching/alg/maze/

当达到“目标”时,我能够到达获取列表,但如果目标无法访问,则列表不会更新。例如

...#@                           !!!#@
..#..                           !!#..
.##.#     it should return      !##.#
...#.                           !!!#.

我的代码如下

path maze x y
    | x >= length (head maze) = (False, maze)
    | y >= length maze = (False, maze)
    | x < 0 = (False, maze)
    | y < 0 = (False,maze)
    | check maze x y '+' = (False, maze)
    | check maze x y '#' = (False,maze)
    | check maze x y '!' = (False, maze)
    | check maze x y 'G' = (True,maze)
    | fst east = (True,snd east)
    | fst south = (True, snd south)
    | fst west = (True, snd west)
    | fst north = (True, snd north)
    | fst noWay = (True, snd noWay)
    | otherwise = (False, maze)
            where 
                    noWay = path (changeVal maze x y '!') x (y+1)
                    north = path(changeVal maze x y '+') x (y-1)
                    south = path (changeVal maze x y '+') x (y+1)
                    east = path (changeVal maze x y '+') (x+1) y
                    west = path (changeVal maze x y '+') (x-1) y

我没有得到结果。我是Haskell的新手,任何人都可以给我一个提升,以便我能解决这个愚蠢的问题。

1 个答案:

答案 0 :(得分:2)

问题的原因似乎就是

| otherwise = (False, maze)

使用原始maze而不是返回更新的版本。但是,即使用snd noWay替换它也不会为您提供所需的输出。 (我认为只有!标记从起点向南的部分。)

存在一个更大的问题:当继续下一个递归步骤时,您的函数不会保留上一步中放置的标记,而是再次从原始maze开始。相反,下一个递归步骤需要从前一个产生的最终迷宫标记开始。例如。 (看到你的守卫向东走 - >向南 - >向西走向>向北走)你需要south离开east完成的地方,比如

south = path (snd east) x (y+1)

如果您同样修正所有路线,则不需要noWay。 (此时将没有任何未标记的位置可供检查。)相反,如果north案例失败,那么它将标记除初始点以外的所有内容,因此您可以执行

| otherwise = (False, changeVal (snd north) x y '!')