|
1 | 1 | package eu.sim642.adventofcode2025 |
2 | 2 |
|
| 3 | +import eu.sim642.adventofcode2018.Day11.SumGrid |
3 | 4 | import eu.sim642.adventofcodelib.box.Box |
4 | 5 | import eu.sim642.adventofcodelib.pos.Pos |
5 | 6 | import eu.sim642.adventofcodelib.SeqImplicits.* |
@@ -31,6 +32,36 @@ object Day9 { |
31 | 32 | _ => true |
32 | 33 | } |
33 | 34 |
|
| 35 | + // Copied & modified from 2018 day 11 |
| 36 | + class ArrayPartialSumGrid(f: Pos => Int, box: Box) extends SumGrid { |
| 37 | + val Box(min, max) = box |
| 38 | + val Pos(width, height) = max - min + Pos(1, 1) |
| 39 | + val partialSums: mutable.ArraySeq[mutable.ArraySeq[Int]] = mutable.ArraySeq.fill(height, width)(0) |
| 40 | + // TODO: should be larger by 1 to allow min-coordinate queries? |
| 41 | + |
| 42 | + for (y <- 0 until height) { |
| 43 | + for (x <- 0 until width) { |
| 44 | + val pos = min + Pos(x, y) |
| 45 | + val sum = |
| 46 | + (if (y >= 1) partialSums(y - 1)(x) else 0) + |
| 47 | + (if (x >= 1) partialSums(y)(x - 1) else 0) - |
| 48 | + (if (x >= 1 && y >= 1) partialSums(y - 1)(x - 1) else 0) + |
| 49 | + f(pos) |
| 50 | + partialSums(y)(x) = sum |
| 51 | + } |
| 52 | + } |
| 53 | + |
| 54 | + override def sumBox(box: Box): Int = { |
| 55 | + //val Box(topLeft, bottomRight) = box |
| 56 | + val topLeft = box.min - min |
| 57 | + val bottomRight = box.max - min |
| 58 | + val bottomLeft1 = Pos(topLeft.x - 1, bottomRight.y) |
| 59 | + val topRight1 = Pos(bottomRight.x, topLeft.y - 1) |
| 60 | + val topLeft1 = Pos(topLeft.x - 1, topLeft.y - 1) |
| 61 | + partialSums(bottomRight.y)(bottomRight.x) - partialSums(bottomLeft1.y)(bottomLeft1.x) - partialSums(topRight1.y)(topRight1.x) + partialSums(topLeft1.y)(topLeft1.x) |
| 62 | + } |
| 63 | + } |
| 64 | + |
34 | 65 | object Part2 extends Part { |
35 | 66 | override def makeIsValid(redTiles: Seq[Pos]): Box => Boolean = { |
36 | 67 | // TODO: clean up |
@@ -73,30 +104,12 @@ object Day9 { |
73 | 104 |
|
74 | 105 | val outside = BFS.traverse(graphTraversal).nodes |
75 | 106 |
|
76 | | - val outsidePrefix = mutable.ArraySeq.fill(ys.size * 2 - 1 + 2, xs.size * 2 - 1 + 2)(0) |
77 | | - for (y <- outsidePrefix.indices) { |
78 | | - for (x <- outsidePrefix(y).indices) { |
79 | | - outsidePrefix(y)(x) = |
80 | | - (if (y >= 1) outsidePrefix(y - 1)(x) else 0) + |
81 | | - (if (x >= 1) outsidePrefix(y)(x - 1) else 0) - |
82 | | - (if (x >= 1 && y >= 1) outsidePrefix(y - 1)(x - 1) else 0) + |
83 | | - (if (outside(Pos(x, y))) 1 else 0) |
84 | | - } |
85 | | - } |
86 | | - |
87 | | - //for (row <- outsidePrefix) { |
88 | | - // for (cell <- row) |
89 | | - // print(s"$cell\t") |
90 | | - // println() |
91 | | - //} |
| 107 | + val outsideSumGrid = new ArrayPartialSumGrid(pos => if (outside(pos)) 1 else 0, Box(Pos.zero, Pos(xs.size * 2, ys.size * 2))) |
92 | 108 |
|
93 | 109 | def isValid(box: Box): Boolean = { |
94 | 110 | val gridBox = Box(mapPos(box.min), mapPos(box.max)) |
95 | 111 | //!gridBox.iterator.exists(outside) |
96 | | - (outsidePrefix(gridBox.max.y)(gridBox.max.x) - |
97 | | - outsidePrefix(gridBox.min.y - 1)(gridBox.max.x) - |
98 | | - outsidePrefix(gridBox.max.y)(gridBox.min.x - 1) + |
99 | | - outsidePrefix(gridBox.min.y - 1)(gridBox.min.x - 1)) == 0 |
| 112 | + outsideSumGrid.sumBox(gridBox) == 0 |
100 | 113 | } |
101 | 114 |
|
102 | 115 | isValid |
|
0 commit comments