@@ -4,6 +4,21 @@ import eu.sim642.adventofcode2017.Day3.Pos
4
4
5
5
object Day6 {
6
6
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
+
7
22
def largestFiniteArea (coords : Seq [Pos ]): Int = {
8
23
def closestCoord (pos : Pos ): Option [Pos ] = {
9
24
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 {
13
28
None
14
29
}
15
30
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)
20
32
21
33
// TODO: optimize with BFS
22
34
val grid = (for {
23
- x <- minX to maxX
24
- y <- minY to maxY
25
- pos = Pos (x, y)
35
+ pos <- iterateRect(min, max)
26
36
coord <- closestCoord(pos)
27
37
} yield pos -> coord).toMap
28
38
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
32
42
}
33
43
34
44
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
43
46
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)
51
49
}
52
50
53
51
private val coordRegex = """ (\d+), (\d+)""" .r
0 commit comments