8000 Extract bounded rectangle iteration in 2018 day 6 · sim642/adventofcode@b5800b7 · GitHub
[go: up one dir, main page]

Skip to content

Commit b5800b7

Browse files
committed
Extract bounded rectangle iteration in 2018 day 6
1 parent 12df544 commit b5800b7

File tree

1 file changed

+23
-25
lines changed
  • src/main/scala/eu/sim642/adventofcode2018

1 file changed

+23
-25
lines changed

src/main/scala/eu/sim642/adventofcode2018/Day6.scala

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,21 @@ import eu.sim642.adventofcode2017.Day3.Pos
44

55
object Day6 {
66

7+
def boundingRect(coords: Seq[Pos]): (Pos, Pos) = {
8+
val minX = coords.minBy(_.x).x
9+
val minY = coords.minBy(_.y).y
10+
val maxX = coords.maxBy(_.x).x
11+
val maxY = coords.maxBy(_.y).y
12+
(Pos(minX, minY), Pos(maxX, maxY))
13+
}
14+
15+
def iterateRect(min: Pos, max: Pos): Iterator[Pos] = {
16+
for {
17+
x <- (min.x to max.x).toIterator
18+
y <- (min.y to max.y).toIterator
19+
} yield Pos(x, y)
20+
}
21+
722
def largestFiniteArea(coords: Seq[Pos]): Int = {
823
def closestCoord(pos: Pos): Option[Pos] = {
924
val Seq((coord1, d1), (coord2, d2)) = coords.toSeq.map(coord => coord -> (coord manhattanDistance pos)).sortBy(_._2).take(2) // TODO: optimize taking only smallest 2
@@ -13,41 +28,24 @@ object Day6 {
1328
None
1429
}
1530

16-
val minX = coords.minBy(_.x).x
17-
val minY = coords.minBy(_.y).y
18-
val maxX = coords.maxBy(_.x).x
19-
val maxY = coords.maxBy(_.y).y
31+
val (min, max) = boundingRect(coords)
2032

2133
// TODO: optimize with BFS
2234
val grid = (for {
23-
x <- minX to maxX
24-
y <- minY to maxY
25-
pos = Pos(x, y)
35+
pos <- iterateRect(min, max)
2636
coord <- closestCoord(pos)
2737
} yield pos -> coord).toMap
2838

29-
val finiteGrid = grid.filterKeys(pos => pos.x != minX && pos.x != maxX && pos.y != minY && pos.y != maxY)
30-
val finiteSizes = finiteGrid.groupBy(_._2).mapValues(_.size)
31-
finiteSizes.values.max
39+
val finiteGrid = grid.filterKeys(pos => pos.x != min.x && pos.x != max.x && pos.y != min.y && pos.y != max.y)
40+
val finiteCoordSizes = finiteGrid.groupBy(_._2).mapValues(_.size)
41+
finiteCoordSizes.values.max
3242
}
3343

3444
def safeArea(coords: Seq[Pos], safeDistance: Int = 10000): Int = {
35-
def totalDistance(pos: Pos): Int = {
36-
coords.map(coord => coord manhattanDistance pos).sum
37-
}
38-
39-
val minX = coords.minBy(_.x).x
40-
val minY = coords.minBy(_.y).y
41-
val maxX = coords.maxBy(_.x).x
42-
val maxY = coords.maxBy(_.y).y
45+
def totalDistance(pos: Pos): Int = coords.map(_ manhattanDistance pos).sum
4346

44-
(for {
45-
x <- minX to maxX
46-
y <- minY to maxY
47-
pos = Pos(x, y)
48-
total = totalDistance(pos)
49-
if total < safeDistance
50-
} yield pos).size
47+
val (min, max) = boundingRect(coords)
48+
iterateRect(min, max).count(totalDistance(_) < safeDistance)
5149
}
5250

5351
private val coordRegex = """(\d+), (\d+)""".r

0 commit comments

Comments
 (0)
0