@@ -36,58 +36,56 @@ val xRange = grid.head.indices
3636val yRange = grid.indices
3737
3838case class Point (x : Int , y : Int ):
39- def inBounds = xRange.contains(x) && yRange.contains(y)
40-
4139 def move (dir : Dir ) = dir match
4240 case Dir .N => copy(y = y - 1 )
4341 case Dir .S => copy(y = y + 1 )
4442 case Dir .E => copy(x = x + 1 )
4543 case Dir .W => copy(x = x - 1 )
4644
45+ def inBounds (p : Point ) =
46+ xRange.contains(p.x) && yRange.contains(p.y)
47+
4748def heatLoss (p : Point ) =
48- if p. inBounds then grid(p.y)(p.x) else 0
49+ if inBounds(p) then grid(p.y)(p.x) else 0
4950
50- case class State (pos : Point , dir : Dir , streak : Int , totalHeatLoss : Int ):
51+ case class State (pos : Point , dir : Dir , streak : Int ):
5152 def straight : State =
52- val newPos = pos.move(dir)
53- State (pos.move(dir), dir, streak + 1 , totalHeatLoss + heatLoss(newPos))
53+ State (pos.move(dir), dir, streak + 1 )
5454
5555 def turnLeft : State =
5656 val newDir = dir.turnLeft
57- val newPos = pos.move(newDir)
58- State (newPos, newDir, 1 , totalHeatLoss + heatLoss(newPos))
57+ State (pos.move(newDir), newDir, 1 )
5958
6059 def turnRight : State =
6160 val newDir = dir.turnRight
62- val newPos = pos.move(newDir)
63- State (pos.move(newDir), newDir, 1 , totalHeatLoss + heatLoss(newPos))
61+ State (pos.move(newDir), newDir, 1 )
6462
6563 def nextStates : List [State ] =
6664 List (straight, turnLeft, turnRight).filter: s =>
67- s.pos.inBounds && s.streak <= 3
65+ inBounds( s.pos) && s.streak <= 3
6866
6967 def nextStates2 : List [State ] =
7068 if streak < 4 then List (straight)
7169 else List (straight, turnLeft, turnRight).filter: s =>
72- s.pos.inBounds && s.streak <= 10
73-
74- def motion = (pos, dir, streak)
70+ inBounds(s.pos) && s.streak <= 10
7571
7672def search (next : State => List [State ]): Int =
77- import collection .mutable .{PriorityQueue , Set }
73+ import collection .mutable .{PriorityQueue , Map }
74+
75+ val minHeatLoss = Map .empty[State , Int ]
7876
79- given Ordering [State ] = Ordering .by(_.totalHeatLoss )
77+ given Ordering [State ] = Ordering .by(minHeatLoss )
8078 val pq = PriorityQueue .empty[State ].reverse
8179
82- var visiting = State (Point (0 , 0 ), Dir .E , 0 , 0 )
83- val visited = Set (visiting.motion)
80+ var visiting = State (Point (0 , 0 ), Dir .E , 0 )
81+ minHeatLoss (visiting) = 0
8482
8583 val end = Point (xRange.max, yRange.max)
8684 while visiting.pos != end do
87- val states = next(visiting).filterNot(s => visited(s.motion) )
88- states.foreach( s => s " enqueuing: $s " )
89- pq.enqueue(states * )
90- visited ++= states.map(_.motion )
85+ val states = next(visiting).filterNot(minHeatLoss.contains )
86+ states.foreach: s =>
87+ minHeatLoss(s) = minHeatLoss(visiting) + heatLoss(s.pos )
88+ pq.enqueue(s )
9189 visiting = pq.dequeue()
9290
93- visiting.totalHeatLoss
91+ minHeatLoss( visiting)
0 commit comments