Skip to content

Commit 8d21abe

Browse files
committed
Solved day12 part 2
1 parent 4b525e8 commit 8d21abe

File tree

4 files changed

+94
-3
lines changed

4 files changed

+94
-3
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ plugins {
44

55
// project meta data
66
group 'de.havox_design.aoc2023'
7-
version '0.11.4'
7+
version '0.11.5'
88

99
// Switch to gradle "all" distribution.
1010
wrapper {

day12/src/main/kotlin/de/havox_design/aoc2023/day12/Day12.kt

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@ package de.havox_design.aoc2023.day12
33
class Day12(private var filename: String) {
44
private val DATA_DELIMITER = " "
55
private val GROUPS_DELIMITER = ","
6+
private val ICON_BROKEN_SPRING = "#"
7+
private val ICON_OPERATIONAL_SPRING = "."
8+
private val ICON_UNKNOWN_SPRING = '?'
9+
10+
// For Quicksolve
11+
private var springs: String = ""
12+
private var sizes: ArrayList<Int> = ArrayList<Int>()
13+
private val cache = HashMap<Pair<Int, Int>, Long>()
614

715
fun solvePart1(): Long =
816
getResourceAsText(filename)
@@ -22,6 +30,76 @@ class Day12(private var filename: String) {
2230
.count()
2331
}
2432

33+
fun quicksolvePart2(): Long {
34+
var sum = 0L
35+
36+
for (row in getResourceAsText(filename)) {
37+
springs = row
38+
.split(DATA_DELIMITER)[0]
39+
val tmpSizes = ArrayList(
40+
row
41+
.split(DATA_DELIMITER)[1]
42+
.split(GROUPS_DELIMITER)
43+
.map { it.toInt() }
44+
.toList()
45+
)
46+
cache.clear()
47+
48+
springs = "$springs?$springs?$springs?$springs?$springs"
49+
sizes.clear();
50+
for (i in 1..5) {
51+
sizes.addAll(tmpSizes)
52+
}
53+
54+
sum += matches("", 0)
55+
}
56+
57+
return sum
58+
}
59+
60+
private fun matched(prefix: String): Boolean =
61+
prefix
62+
.filterIndexed { index, c -> c == springs[index] || springs[index] == ICON_UNKNOWN_SPRING }
63+
.count() == prefix.length
64+
65+
@SuppressWarnings("kotlin:S6611", "kotlin:S6510")
66+
private fun matches(prefix: String, group: Int): Long {
67+
when {
68+
prefix.length > springs.length -> return 0
69+
cache.contains(Pair(prefix.length, group)) -> {
70+
return cache[Pair(prefix.length, group)]!!
71+
}
72+
73+
group == sizes.size -> {
74+
return when {
75+
matched(prefix + ICON_OPERATIONAL_SPRING.repeat(springs.length - prefix.length)) -> 1
76+
else -> 0
77+
}
78+
}
79+
80+
else -> {
81+
var result: Long = 0
82+
83+
for (i in 0..<(springs.length - sizes[group])) {
84+
var p = prefix;
85+
86+
when {
87+
group > 0 -> p += ICON_OPERATIONAL_SPRING
88+
}
89+
90+
p += ICON_OPERATIONAL_SPRING.repeat(i) + ICON_BROKEN_SPRING.repeat(sizes[group])
91+
92+
when {
93+
p.length <= springs.length && matched(p) -> result += matches(p, group + 1)
94+
}
95+
}
96+
97+
cache[Pair(prefix.length, group)] = result
98+
return result
99+
}
100+
}
101+
}
102+
25103
private fun parseInput(row: String, folded: Boolean = false): Record {
26104
val (text, groups) = row
27105
.split(DATA_DELIMITER)
@@ -33,7 +111,13 @@ class Day12(private var filename: String) {
33111
folded -> {
34112
Record(
35113
"$text?$text?$text?$text?$text",
36-
listOf(groupDistribution, groupDistribution, groupDistribution, groupDistribution, groupDistribution)
114+
listOf(
115+
groupDistribution,
116+
groupDistribution,
117+
groupDistribution,
118+
groupDistribution,
119+
groupDistribution
120+
)
37121
.flatten()
38122
)
39123
}

day12/src/main/kotlin/de/havox_design/aoc2023/day12/MainClass.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ class MainClass {
77
val filename = "day12.txt"
88

99
println("Solution part 1: ${Day12(filename).solvePart1()}")
10-
println("Solution part 2: ${Day12(filename).solvePart2()}")
10+
println("Solution part 2: ${Day12(filename).quicksolvePart2()}")
1111
}
1212
}
1313
}

day12/src/test/kotlin/de/havox_design/aoc2023/day12/Day12Test.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package de.havox_design.aoc2023.day12
22

33
import org.junit.jupiter.api.Assertions.assertEquals
4+
import org.junit.jupiter.api.Disabled
45
import org.junit.jupiter.api.Test
56
import org.junit.jupiter.params.ParameterizedTest
67
import org.junit.jupiter.params.provider.Arguments
@@ -18,11 +19,17 @@ class Day12Test {
1819
fun testSolvePart1(filename: String, expectedResult: Long) =
1920
Day12(filename).solvePart1().shouldBe(expectedResult)
2021

22+
@Disabled("takes much toooooooooooooooooo long...")
2123
@ParameterizedTest
2224
@MethodSource("getDataForTestSolvePart2")
2325
fun testSolvePart2(filename: String, expectedResult: Long) =
2426
Day12(filename).solvePart2().shouldBe(expectedResult)
2527

28+
@ParameterizedTest
29+
@MethodSource("getDataForTestSolvePart2")
30+
fun testQuicksolvePart2(filename: String, expectedResult: Long) =
31+
Day12(filename).quicksolvePart2().shouldBe(expectedResult)
32+
2633
companion object {
2734
@JvmStatic
2835
private fun getDataForTestSolvePart1(): Stream<Arguments> =

0 commit comments

Comments
 (0)