@@ -3,6 +3,14 @@ package de.havox_design.aoc2023.day12
33class 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 }
0 commit comments