Skip to content

Commit c93ec0e

Browse files
authored
update 2023 day 17 to simplify State and use heatloss Map (#514)
1 parent d7fac63 commit c93ec0e

File tree

1 file changed

+21
-23
lines changed

1 file changed

+21
-23
lines changed

2023/src/day17.scala

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -36,58 +36,56 @@ val xRange = grid.head.indices
3636
val yRange = grid.indices
3737

3838
case 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+
4748
def 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

7672
def 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

Comments
 (0)