我的Haskell课程有这个任务,但我觉得很难。如果你能帮助一点。 你有一个迷宫
maze = ["x xxx",
"x x",
"x x x",
"x x ",
"xxxxx"]
你只能走过空间。你从(0,1)开始,函数必须返回一个字符串,其中包含避开迷宫的方向:
f - forward
r- turn right
l - turn left
如果你有一个选择,你总是喜欢向前,向前向左。
对于当前示例,答案为ffllffrffrfflf
提前致谢
data Direction = N | W | S | E deriving (Show,Eq)
maze = ["x xxx",
"x x",
"x x x",
"x x ",
"xxxxx"]
d = 's'
pos = (0,1)
fpath d pos | fst pos == (length maze - 1) = ""
| snd (pos) ==0 || (snd ( pos ) == ((length (maze!!0))-1)) = ""
| rightPossible d pos = "r" ++ ( fpath (rightRotate d) pos )
| forwardPossible d pos = "f" ++ ( fpath d (nstep d pos) )
| True = "l" ++ fpath (leftRotate d) pos
where nstep :: Direction -> (Int, Int) -> (Int, Int) {-next step-}
nstep N (x,y) = (x-1,y)
nstep W (x,y) = (x,y-1)
nstep S (x,y) = (x+1,y)
nstep E (x,y) = (x,y+1)
rightPossible :: Direction -> (Int, Int) -> Bool
rightPossible N (x,y)= (maze !! x)!! (y+1) == ' '
rightPossible W (x,y)= (maze !! (x-1))!! y == ' '
rightPossible S (x,y)= (maze !! x)!! (y-1) == ' '
rightPossible E (x,y)= (maze !! (x+1))!! y == ' '
rightRotate :: Direction -> Direction
rightRotate N = E
rightRotate W = N
rightRotate S = W
rightRotate E = S
forwardPossible :: Direction -> (Int, Int) -> Bool
forwardPossible N (x,y)= ((maze !! (x-1))!! y) == ' '
forwardPossible W (x,y)= ((maze !! x)!! (y-1)) == ' '
forwardPossible S (x,y)= ((maze !! (x+1))!! y) == ' '
forwardPossible E (x,y)= ((maze !! x)!! (y+1)) == ' '
leftRotate :: Direction -> Direction
leftRotate N = W
leftRotate W = S
leftRotate S = E
leftRotate E = N
答案 0 :(得分:7)
我看到的第一件事是,你有一个优先问题。表达式(maze !! x)!! y-1
被解析为((maze !! x)!! y)-1
,而您希望将其解析为(maze !! x)!! (y-1)
。添加大括号来解决此问题。
添加此内容后,您的代码会编译,但您的算法似乎已被破坏。也许其他人可以帮助你。
一些编码建议:
使用模式匹配而不是额外的case语句。而不是
nstep d (x,y) {-next step-}
| d == 'n' = (x-1,y)
| d == 'w' = (x,y-1)
| d == 's' = (x+1,y)
| d == 'e' = (x,y+1)
写
nstep 'n' (x,y) = (x-1,y)
nstep 'w' (x,y) = (x,y-1)
nstep 's' (x,y) = (x+1,y)
nstep 'e' (x,y) = (x,y+1)
编写您自己的data
类型,而不是依赖于字符。例如,您可以为方向创建自己的数据类型:
data Direction = N | W | S | E deriving (Show,Eq)
答案 1 :(得分:2)
我同意FUZxxl。如果您创建新数据类型,则可以执行
之类的操作数据类型
data Direction = North | West | South | East deriving (Show,Eq) type Point = (Int, Int)
以可读且有效的方式使用数据类型
nstep :: Direction -> Point -> Point nstep North (x,y) = (x-1,y) nstep West (x,y) = (x,y-1) nstep South (x,y) = (x+1,y) nstep East (x,y) = (x,y+1)
再来一次。另外,使用命名良好的函数而不仅仅是r
,这并不意味着什么。
rightPossible :: Direction -> Point -> Bool rightPossible North = (maze !! x)!! (y-1) == ' ' rightPossible West = (maze !! x+1)!! y == ' ' rightPossible South = (maze !! x)!! (y+1) == ' ' rightPossible East = (maze !! x-1)!! y == ' '
希望这有助于您理解语言。
修改:将data Point
更改为type Point