Skip to content

Commit 7f9d925

Browse files
committed
08
1 parent c15c980 commit 7f9d925

File tree

5 files changed

+199
-17
lines changed

5 files changed

+199
-17
lines changed

.idea/workspace.xml

Lines changed: 27 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main/kotlin/08.kt

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
fun main() {
2+
println(solve08a(readInputLines("08")))
3+
println(solve08b(readInputLines("08")))
4+
}
5+
6+
fun solve08a(lines: List<String>): Int {
7+
val (size, antennas) = parseInput(lines)
8+
return antennas.values.flatMap { getAntinodeLocations(size, it) }.toSet().size
9+
}
10+
11+
fun solve08b(lines: List<String>): Int {
12+
val (size, antennas) = parseInput(lines)
13+
return antennas.values.flatMap { getAntinodeLocations2(size, it) }.toSet().size
14+
}
15+
16+
private data class City(val size: Vector, val antennas: Map<Char, Set<Point>>)
17+
18+
private fun parseInput(lines: List<String>): City {
19+
val antennas = mutableMapOf<Char, Set<Point>>()
20+
21+
for ((y, line) in lines.withIndex()) {
22+
for ((x, c) in line.withIndex()) {
23+
if (c == '.') {
24+
continue
25+
}
26+
27+
val existing = antennas.getOrDefault(c, setOf())
28+
antennas[c] = existing + setOf(Point(x, y))
29+
}
30+
}
31+
32+
return City(Vector(lines[0].length, lines.size), antennas)
33+
}
34+
35+
private fun getAntinodeLocations(size: Vector, antennas: Set<Point>): Set<Point> {
36+
val result = mutableSetOf<Point>()
37+
val list = antennas.toList()
38+
39+
for (i in antennas.indices) {
40+
for (j in i + 1 until antennas.size) {
41+
val delta = Vector(list[j].x - list[i].x, list[j].y - list[i].y)
42+
result.add(Point(list[i].x - delta.x, list[i].y - delta.y))
43+
result.add(Point(list[j].x + delta.x, list[j].y + delta.y))
44+
}
45+
}
46+
47+
return result.filter { isPointInBounds(size, it) }.toSet()
48+
}
49+
50+
private fun getAntinodeLocations2(size: Vector, antennas: Set<Point>): Set<Point> {
51+
val result = mutableSetOf<Point>()
52+
val list = antennas.toList()
53+
54+
for (i in antennas.indices) {
55+
for (j in i + 1 until antennas.size) {
56+
result.addAll(getPointsInLine(list[i], list[j], size))
57+
}
58+
}
59+
60+
return result
61+
}
62+
63+
private fun getPointsInLine(antenna1: Point, antenna2: Point, size: Vector): Set<Point> {
64+
val delta = simplifyDelta(Vector(antenna2.x - antenna1.x, antenna2.y - antenna1.y))
65+
val result = mutableSetOf<Point>()
66+
67+
var current = antenna1
68+
while (isPointInBounds(size, current)) {
69+
result.add(current)
70+
current = Point(current.x - delta.x, current.y - delta.y)
71+
}
72+
current = antenna1
73+
while (isPointInBounds(size, current)) {
74+
result.add(current)
75+
current = Point(current.x + delta.x, current.y + delta.y)
76+
}
77+
78+
return result
79+
}
80+
81+
private fun simplifyDelta(delta: Vector): Vector =
82+
when {
83+
delta.x == 0 -> Vector(0, 1)
84+
delta.y == 0 -> Vector(1, 0)
85+
else -> {
86+
val gcd = delta.x.toBigInteger().gcd(delta.y.toBigInteger()).toInt()
87+
Vector(delta.x / gcd, delta.y / gcd)
88+
}
89+
}
90+
91+
private fun isPointInBounds(size: Vector, point: Point): Boolean =
92+
point.x >= 0 && point.x < size.x && point.y >= 0 && point.y < size.y

src/main/kotlin/input/08.txt

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
..........M..........j.............y.....O........
2+
...B...............q......m........lGO............
3+
....................q......2.l.GQ...O.............
4+
.....X.......................................4....
5+
.....................q............................
6+
....M......P...............xl.K.............2.....
7+
....F.........L.......C.K..............m..........
8+
..........FM......P....jy......m..........o...r...
9+
..X.......P.....RL..............G..x..........4...
10+
............L..........NC.....q...................
11+
.....C.X...............K....y..........4..........
12+
........S...R.............j.x.....V...4...........
13+
.....................R..x.....V..i......m.........
14+
...........................R.V......N.......X.....
15+
.....F.........M......N......E....................
16+
................v................T.......F......O.
17+
.............................N...V.......Q........
18+
...v.....................C.....i..................
19+
......c.....W..n.w........................E.......
20+
3...................c.....................Q..6....
21+
...........h......................j...............
22+
.......n.0......h.................E..............2
23+
.v.............7.......120.....c..................
24+
......n.0............w...........D.t.........E...r
25+
....8..3......0.w.hP....z...D..T...............r..
26+
.................f........T........G......eQ......
27+
......f.n.....7..p................................
28+
.....Y..7.......f......I......D......K............
29+
............Uf....T..W.....D..r...i...............
30+
......I...............................Z...........
31+
....5....B.......b..............s..............Z..
32+
..........d...W..Uwh.............c..........i.....
33+
..I.3..Y......................e...................
34+
.....p.b..........k......7........................
35+
p...........k....I..b..........s..................
36+
.....k.......o...........W........................
37+
.A..Y..........U.................a........6.......
38+
..A...Y.p...................................6.....
39+
B......k..........................Z............u..
40+
...3.....................s..............a.........
41+
......A.........................g.....a...........
42+
.......A....8...b.U......H....sS..................
43+
.........................S1.............t.........
44+
.....................9z..e.....5..1.g.u...........
45+
.......................z....d....g....H.J....o.6..
46+
........B................d.....u....9.J.H.........
47+
.8........S.................u9.............J.....H
48+
.....................Z5.............t1...........a
49+
.....................e..v...................o..t..
50+
.....8...............L.....z.............J........

src/main/kotlin/input/08_example1.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
............
2+
........0...
3+
.....0......
4+
.......0....
5+
....0.......
6+
......A.....
7+
............
8+
............
9+
........A...
10+
.........A..
11+
............
12+
............

src/test/kotlin/Test08.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import org.junit.Assert.assertEquals
2+
import org.junit.Test
3+
4+
class Test08 {
5+
@Test
6+
fun test_a() {
7+
val result = solve08a(readInputLines("08_example1"))
8+
9+
assertEquals(14, result)
10+
}
11+
12+
@Test
13+
fun test_b() {
14+
val result = solve08b(readInputLines("08_example1"))
15+
16+
assertEquals(34, result)
17+
}
18+
}

0 commit comments

Comments
 (0)