我在Haskell的编程任务中挣扎。 我必须写一个函数:
move ::([Move],Towers) -> ([Move],Towers)
获取移动列表和游戏配置。该函数必须检查第一次移动是否有效,然后执行此移动。您可以在下面看到该功能的可能输出。我对Haskell很陌生,这个编程任务对我来说很重要。我不知道如何以及从哪里开始。解决这个问题的基本策略是什么?我真的很想学习它,如果你能给我一些建议,我会很高兴。
由于
type Position = Int
type Move = (Position,Position)
type Towers = ([Int],[Int],[Int])
hanoi :: Int -> Position -> Position -> [Move]
hanoi 1 i j = [(i, j)]
hanoi n i j = (hanoi (n-1) i other) ++ [(i, j)] ++ (hanoi (n-1) other j)
where
other = 1+2+3-i-j
输出:move ::([Move],Towers) -> ([Move],Towers)
> hanoi 3 1 3 [(1,3),(1,2),(3,2),(1,3),(2,1),(2,3),(1,3)]
> move (it, ([1,2,3],[],[])) ([(1,2),(3,2),(1,3),(2,1),(2,3),(1,3)],([2,3],[],[1]))
> move it ([(3,2),(1,3),(2,1),(2,3),(1,3)],([3],[2],[1]))
> move it ([(1,3),(2,1),(2,3),(1,3)],([3],[1,2],[]))
> move ([(1,4)],([3],[1,2],[])) ([],*** Exception: Move not valid!
> move ([(1,2),(1,3)],([3,4],[1,2],[])) ([(2,3)],([4],*** Exception: Disc is to big!
答案 0 :(得分:2)
move ::([Move],Towers) -> ([Move],Towers)
move ([],t) = ([],t)
move (x:xs,t) = move (xs,move1 x t)
move1::Move->Towers->Towers
move1 (i,j) (a,b,c)
| i==1 && j==2 && not (null a) = if inf a b then (tail a,head a:b,c) else error "Disk too large"
| i==1 && j==3 && not (null a) = if inf a c then (tail a,b,head a:c) else error "Disk too large"
| i==2 && j==1 && not (null b) = if inf b a then (head b:a,tail b,c) else error "Disk too large"
| i==2 && j==3 && not (null b) = if inf b c then (a,tail b,head b:c) else error "Disk too large"
| i==3 && j==1 && not (null c) = if inf c a then (head c:a,b,tail c) else error "Disk too large"
| i==3 && j==2 && not (null c) = if inf c b then (a,head c:b,tail c) else error "Disk too large"
| otherwise = error "Move not valid"
inf :: [Int]->[Int]->Bool
inf a b = null b || head a < minimum b