@@ -33,7 +33,10 @@ turns R = [U,D]
33
33
(x,y) >>> L = (x- 1 ,y)
34
34
(x,y) >>> R = (x+ 1 ,y)
35
35
36
- nexts (cost,pos,dir,ps) = (cost+ 1 ,pos >>> dir, dir, pos: ps): [(cost+ 1000 ,pos,dir',ps) | dir' <- turns dir]
36
+ type State = (Int ,Pos ,Dir ,[Pos ]) -- (cost,pos,dir,previous positions)
37
+
38
+ neighbours :: State -> [State ]
39
+ neighbours (cost,pos,dir,ps) = (cost+ 1 ,pos >>> dir, dir, pos: ps): [(cost+ 1000 ,pos,dir',ps) | dir' <- turns dir]
37
40
38
41
orderedUnion new old = foldr insert old (sort new)
39
42
@@ -49,12 +52,13 @@ visualize paths visited = unlines [ [ r (x,y) | x <- [0..maxX] ] | y <- [0..maxY
49
52
50
53
dijkstra :: (Pos ,Pos ,Paths ) -> [(Int ,[Pos ])]
51
54
dijkstra (start,end,paths) = go S. empty [(0 ,start,R ,[] )]
52
- where go :: S. Set (Pos ,Dir ) -> [( Int , Pos , Dir ,[ Pos ]) ] -> [(Int ,[Pos ])]
55
+ where go :: S. Set (Pos ,Dir ) -> [State ] -> [(Int ,[Pos ])]
53
56
go visited (s@ (cost,pos,dir,_): ss)
54
- | pos == end = [(cost,pos: ps) | (cost,pos,_,ps) <- s: ss, pos== end]
57
+ | pos == end = [(cost,pos: ps) | (cost' ,pos' ,_,ps) <- s: ss, pos' == end, cost' == cost ]
55
58
| otherwise = -- trace (visualize paths visited) $
56
59
-- trace ("Q: "++show (s:ss)) $
57
- go (S. insert (pos,dir) visited) (orderedUnion (filter (possible visited) $ nexts s) ss)
60
+ go (S. insert (pos,dir) visited) (orderedUnion (nexts visited s) ss)
61
+ nexts visited s = filter (possible visited) $ neighbours s
58
62
possible visited (_,p,dir,_) = S. member p paths && not (S. member (p,dir) visited)
59
63
60
64
part1 = fst . head . dijkstra
0 commit comments