@@ -25,39 +25,97 @@ object Day20 {
2525 }
2626 }
2727
28- def findCheats (grid : Grid [Char ]): Set [Cheat ] = {
29- val forwardSearch = gridGraphSearch(grid, 'S' , 'E' )
30- val forwardResult = BFS .search(forwardSearch)
31- val backwardSearch = gridGraphSearch(grid, 'E' , 'S' )
32- val backwardResult = BFS .search(backwardSearch)
33-
34- val noCheatDistance = forwardResult.target.get._2
35-
36- (for {
37- (row, y) <- grid.view.zipWithIndex
38- (cell, x) <- row.view.zipWithIndex
39- if cell == '#'
40- pos = Pos (x, y)
41- startOffset <- Pos .axisOffsets
42- start = pos + startOffset
43- if grid.containsPos(start) && grid(start) != '#'
44- endOffset <- Pos .axisOffsets
45- if startOffset != endOffset
46- end = pos + endOffset
47- if grid.containsPos(end) && grid(end) != '#'
48- cheatDistance = forwardResult.distances(start) + 2 + backwardResult.distances(end)
49- // if cheatDistance <= noCheatDistance
50- save = noCheatDistance - cheatDistance
51- } yield Cheat (start, end, save)).toSet
28+ trait Part {
29+ def findCheats (grid : Grid [Char ]): Set [Cheat ]
30+
31+ def countGoodCheats (grid : Grid [Char ]): Int = findCheats(grid).count(_.save >= 100 )
32+ }
33+
34+ object Part1 extends Part {
35+ override def findCheats (grid : Grid [Char ]): Set [Cheat ] = {
36+ val forwardSearch = gridGraphSearch(grid, 'S' , 'E' )
37+ val forwardResult = BFS .search(forwardSearch)
38+ val backwardSearch = gridGraphSearch(grid, 'E' , 'S' )
39+ val backwardResult = BFS .search(backwardSearch)
40+
41+ val noCheatDistance = forwardResult.target.get._2
42+
43+ (for {
44+ (row, y) <- grid.view.zipWithIndex
45+ (cell, x) <- row.view.zipWithIndex
46+ if cell == '#'
47+ pos = Pos (x, y)
48+ startOffset <- Pos .axisOffsets
49+ start = pos + startOffset
50+ if grid.containsPos(start) && grid(start) != '#'
51+ endOffset <- Pos .axisOffsets
52+ if startOffset != endOffset
53+ end = pos + endOffset
54+ if grid.containsPos(end) && grid(end) != '#'
55+ cheatDistance = forwardResult.distances(start) + 2 + backwardResult.distances(end)
56+ // if cheatDistance <= noCheatDistance
57+ save = noCheatDistance - cheatDistance
58+ } yield Cheat (start, end, save)).toSet
59+ }
5260 }
5361
54- def countGoodCheats (grid : Grid [Char ]): Int = findCheats(grid).count(_.save >= 100 )
62+ object Part2 extends Part {
63+ override def findCheats (grid : Grid [Char ]): Set [Cheat ] = {
64+ val forwardSearch = gridGraphSearch(grid, 'S' , 'E' )
65+ val forwardResult = BFS .search(forwardSearch)
66+ val backwardSearch = gridGraphSearch(grid, 'E' , 'S' )
67+ val backwardResult = BFS .search(backwardSearch)
68+
69+ val noCheatDistance = forwardResult.target.get._2
70+
71+ // TODO: optimize
72+
73+ /* (for {
74+ (row, y) <- grid.view.zipWithIndex
75+ (cell, x) <- row.view.zipWithIndex
76+ if cell == '.'
77+ start = Pos(x, y)
78+ startOffset <- Pos.axisOffsets
79+ startCheat <- 0 to 20
80+ pos = start + startCheat *: startOffset
81+ if grid.containsPos(pos)
82+ endOffset <- Pos.axisOffsets
83+ if startOffset != endOffset && startOffset != -endOffset
84+ endCheat <- 0 to (20 - startCheat)
85+ end = pos + endCheat *: endOffset
86+ if grid.containsPos(end) && grid(end) != '#'
87+ cheatDistance = forwardResult.distances(start) + (startCheat + endCheat) + backwardResult.distances(end)
88+ //if cheatDistance <= noCheatDistance
89+ save = noCheatDistance - cheatDistance
90+ } yield Cheat(start, end, save)).toSet*/
91+
92+ (for {
93+ (row, y) <- grid.view.zipWithIndex
94+ (cell, x) <- row.view.zipWithIndex
95+ if cell != '#'
96+ start = Pos (x, y)
97+ xOffset <- - 20 to 20
98+ pos = start + Pos (xOffset, 0 )
99+ if grid.containsPos(pos)
100+ startCheat = xOffset.abs
101+ maxEndCheat = 20 - startCheat
102+ yOffset <- (- maxEndCheat) to maxEndCheat
103+ end = pos + Pos (0 , yOffset)
104+ if grid.containsPos(end) && grid(end) != '#'
105+ endCheat = yOffset.abs
106+ cheatDistance = forwardResult.distances(start) + (startCheat + endCheat) + backwardResult.distances(end)
107+ // if cheatDistance <= noCheatDistance
108+ save = noCheatDistance - cheatDistance
109+ } yield Cheat (start, end, save)).toSet
110+ }
111+ }
55112
56113 def parseGrid (input : String ): Grid [Char ] = input.linesIterator.map(_.toVector).toVector
57114
58115 lazy val input : String = scala.io.Source .fromInputStream(getClass.getResourceAsStream(" day20.txt" )).mkString.trim
59116
60117 def main (args : Array [String ]): Unit = {
61- println(countGoodCheats(parseGrid(input)))
118+ println(Part1 .countGoodCheats(parseGrid(input)))
119+ println(Part2 .countGoodCheats(parseGrid(input)))
62120 }
63121}
0 commit comments