Skip to content

Commit ae9fffd

Browse files
authored
Day 19 2024 (#282)
1 parent 1bf9317 commit ae9fffd

File tree

4 files changed

+82
-0
lines changed

4 files changed

+82
-0
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package me.peckb.aoc._2024.calendar.day19
2+
3+
import javax.inject.Inject
4+
import me.peckb.aoc.generators.InputGenerator.InputGeneratorFactory
5+
6+
class Day19 @Inject constructor(
7+
private val generatorFactory: InputGeneratorFactory,
8+
) {
9+
fun partOne(filename: String) = generatorFactory.forFile(filename).read { input ->
10+
val data = input.toList()
11+
val availableTowelTypes = data.first().split(", ")
12+
13+
data.drop(2).count { pattern -> isPossible(pattern, availableTowelTypes) }
14+
}
15+
16+
fun partTwo(filename: String) = generatorFactory.forFile(filename).read { input ->
17+
val data = input.toList()
18+
val availableTowelTypes = data.first().split(", ")
19+
20+
data.drop(2).sumOf { pattern -> isPossibleCount(pattern, availableTowelTypes) }
21+
}
22+
23+
private fun isPossible(pattern: String, availableTowelTypes: List<String>): Boolean {
24+
if (pattern.isEmpty()) return true
25+
if (found[pattern] == false) return false
26+
27+
return availableTowelTypes.any { towel ->
28+
pattern.startsWith(towel) && isPossible(pattern.substring(towel.length), availableTowelTypes)
29+
}.also { found[pattern] = it }
30+
}
31+
32+
private fun isPossibleCount(pattern: String, availableTowelTypes: List<String>): Long {
33+
if (pattern.isEmpty()) return 1
34+
foundCount[pattern]?.let { return it }
35+
36+
return availableTowelTypes.sumOf { towel ->
37+
if (!pattern.startsWith(towel)) { 0L } else {
38+
isPossibleCount(pattern.substring(towel.length), availableTowelTypes)
39+
}
40+
}.also { foundCount[pattern] = it }
41+
}
42+
43+
companion object {
44+
val found = mutableMapOf<String, Boolean>()
45+
val foundCount = mutableMapOf<String, Long>()
46+
}
47+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
## [Day 19: Linen Layout](https://adventofcode.com/2024/day/19)

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import me.peckb.aoc._2024.calendar.day15.Day15Test
1818
import me.peckb.aoc._2024.calendar.day16.Day16Test
1919
import me.peckb.aoc._2024.calendar.day17.Day17Test
2020
import me.peckb.aoc._2024.calendar.day18.Day18Test
21+
import me.peckb.aoc._2024.calendar.day19.Day19Test
2122
import javax.inject.Singleton
2223
import me.peckb.aoc.DayComponent
2324
import me.peckb.aoc.InputModule
@@ -44,4 +45,5 @@ internal interface TestDayComponent : DayComponent {
4445
fun inject(day16Test: Day16Test)
4546
fun inject(day17Test: Day17Test)
4647
fun inject(day18Test: Day18Test)
48+
fun inject(day19Test: Day19Test)
4749
}
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.day19
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 Day19Test {
11+
@Inject
12+
lateinit var day19: Day19
13+
14+
@BeforeEach
15+
fun setup() {
16+
DaggerTestDayComponent.create().inject(this)
17+
}
18+
19+
@Test
20+
fun testDay19PartOne() {
21+
assertEquals(255, day19.partOne(DAY_19))
22+
}
23+
24+
@Test
25+
fun testDay19PartTwo() {
26+
assertEquals(621820080273474, day19.partTwo(DAY_19))
27+
}
28+
29+
companion object {
30+
private const val DAY_19: String = "advent-of-code-input/2024/day19.input"
31+
}
32+
}

0 commit comments

Comments
 (0)