@@ -25,39 +25,97 @@ object Day20 {
25
25
}
26
26
}
27
27
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
+ }
52
60
}
53
61
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
+ }
55
112
56
113
def parseGrid (input : String ): Grid [Char ] = input.linesIterator.map(_.toVector).toVector
57
114
58
115
lazy val input : String = scala.io.Source .fromInputStream(getClass.getResourceAsStream(" day20.txt" )).mkString.trim
59
116
60
117
def main (args : Array [String ]): Unit = {
61
- println(countGoodCheats(parseGrid(input)))
118
+ println(Part1 .countGoodCheats(parseGrid(input)))
119
+ println(Part2 .countGoodCheats(parseGrid(input)))
62
120
}
63
121
}
0 commit comments