Skip to content

Commit 2205930

Browse files
committed
Day 23 2024
1 parent 796a473 commit 2205930

File tree

4 files changed

+106
-0
lines changed

4 files changed

+106
-0
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package me.peckb.aoc._2024.calendar.day23
2+
3+
import javax.inject.Inject
4+
import me.peckb.aoc.generators.InputGenerator.InputGeneratorFactory
5+
6+
class Day23 @Inject constructor(
7+
private val generatorFactory: InputGeneratorFactory,
8+
) {
9+
fun partOne(filename: String) = generatorFactory.forFile(filename).readAs(::connection) { input ->
10+
val connections = findFriends(input)
11+
val triplets = mutableSetOf<Set<String>>()
12+
13+
findCommonFriend(connections) { me, them, ourFriends ->
14+
ourFriends.forEach { ourFriend -> triplets.add(setOf(me, them, ourFriend)) }
15+
}
16+
17+
triplets.count { group -> group.any { it.startsWith('t') } }
18+
}
19+
20+
fun partTwo(filename: String) = generatorFactory.forFile(filename).readAs(::connection) { input ->
21+
val connections = findFriends(input)
22+
val friends = mutableSetOf<Set<String>>()
23+
24+
findCommonFriend(connections) { me, them, ourFriends ->
25+
if (ourFriends.isNotEmpty()) {
26+
val everyFriend = ourFriends.all { maybeMutual ->
27+
ourFriends.minus(maybeMutual).all {
28+
(maybeMutual in connections[it]!!)
29+
}
30+
}
31+
if (everyFriend) {
32+
friends.add(ourFriends.plus(me).plus(them))
33+
}
34+
}
35+
}
36+
37+
friends.maxBy { it.size }.toList().sorted().joinToString(",")
38+
}
39+
40+
private fun connection(line: String) : Pair<String, String> {
41+
return line.split("-").let { (a, b) -> a to b }
42+
}
43+
44+
private fun findFriends(input: Sequence<Pair<String, String>>): MutableMap<String, Set<String>> {
45+
val connections = mutableMapOf<String, Set<String>>()
46+
47+
input.forEach { (c1, c2) ->
48+
connections.merge(c1, setOf(c2)) { a, b -> a + b }
49+
connections.merge(c2, setOf(c1)) { a, b -> a + b }
50+
}
51+
52+
return connections
53+
}
54+
55+
private fun findCommonFriend(connections: Map<String, Set<String>>, handleFriends: (String, String, Set<String>) -> Unit) {
56+
val keys = connections.keys.toList()
57+
(0 until keys.size - 2).forEach { i ->
58+
val me = keys[i]
59+
val myFriends = connections[me]!!
60+
61+
(i + 1 until keys.size - 1).forEach { j ->
62+
val them = keys[j]
63+
val theirFriends = connections[them]!!
64+
65+
if (me in theirFriends) {
66+
handleFriends(me, them, myFriends.intersect(theirFriends))
67+
}
68+
}
69+
}
70+
}
71+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
## [Day 23: LAN Party](https://adventofcode.com/2024/day/23)

src/test/kotlin/me/peckb/aoc/_2024/TestDayComponent.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import me.peckb.aoc._2024.calendar.day19.Day19Test
2222
import me.peckb.aoc._2024.calendar.day20.Day20Test
2323
import me.peckb.aoc._2024.calendar.day21.Day21Test
2424
import me.peckb.aoc._2024.calendar.day22.Day22Test
25+
import me.peckb.aoc._2024.calendar.day23.Day23Test
2526
import javax.inject.Singleton
2627
import me.peckb.aoc.DayComponent
2728
import me.peckb.aoc.InputModule
@@ -52,4 +53,5 @@ internal interface TestDayComponent : DayComponent {
5253
fun inject(day20Test: Day20Test)
5354
fun inject(day21Test: Day21Test)
5455
fun inject(day22Test: Day22Test)
56+
fun inject(day23Test: Day23Test)
5557
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package me.peckb.aoc._2024.calendar.day23
2+
3+
import javax.inject.Inject
4+
5+
import me.peckb.aoc._2024.DaggerTestDayComponent
6+
import org.junit.jupiter.api.Assertions.assertEquals
7+
import org.junit.jupiter.api.BeforeEach
8+
import org.junit.jupiter.api.Test
9+
10+
internal class Day23Test {
11+
@Inject
12+
lateinit var day23: Day23
13+
14+
@BeforeEach
15+
fun setup() {
16+
DaggerTestDayComponent.create().inject(this)
17+
}
18+
19+
@Test
20+
fun testDay23PartOne() {
21+
assertEquals(998, day23.partOne(DAY_23))
22+
}
23+
24+
@Test
25+
fun testDay23PartTwo() {
26+
assertEquals("cc,ff,fh,fr,ny,oa,pl,rg,uj,wd,xn,xs,zw", day23.partTwo(DAY_23))
27+
}
28+
29+
companion object {
30+
private const val DAY_23: String = "advent-of-code-input/2024/day23.input"
31+
}
32+
}

0 commit comments

Comments
 (0)