Skip to content

Commit 9a9ac6e

Browse files
committed
Solved day12 part 1
1 parent 394b77d commit 9a9ac6e

File tree

3 files changed

+123
-2
lines changed

3 files changed

+123
-2
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.1'
7+
version '0.11.2'
88

99
// Switch to gradle "all" distribution.
1010
wrapper {
Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,33 @@
11
package de.havox_design.aoc2023.day12
22

33
class Day12(private var filename: String) {
4+
private val DATA_DELIMITER = " "
5+
private val GROUPS_DELIMITER = ","
6+
47
fun solvePart1(): Long =
5-
21L
8+
getResourceAsText(filename)
9+
.map { parseInput(it) }
10+
.sumOf {
11+
it
12+
.possibleGroups
13+
.count()
14+
}
615

716
fun solvePart2(): Long =
817
0L
918

19+
private fun parseInput(row: String): Record {
20+
val (text, groups) = row
21+
.split(DATA_DELIMITER)
22+
23+
return Record(
24+
text,
25+
groups
26+
.split(GROUPS_DELIMITER)
27+
.map { it.toInt() }
28+
)
29+
}
30+
1031
private fun getResourceAsText(path: String): List<String> =
1132
this.javaClass.classLoader.getResourceAsStream(path)!!.bufferedReader().readLines()
1233
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package de.havox_design.aoc2023.day12
2+
3+
import kotlin.streams.asStream
4+
5+
data class Record(val text: String, val groups: List<Int>) {
6+
private val ICON_BROKEN_SPRING = '#'
7+
private val ICON_OPERATIONAL_SPRING = '.'
8+
private val ICON_UNKNOWN_SPRING = '?'
9+
10+
private val possibilities = replaceQuestionmark(sequenceOf(text), text.count { it == '?' })
11+
val possibleGroups = possibilities
12+
.asStream()
13+
.parallel()
14+
.map {
15+
it
16+
.split(ICON_OPERATIONAL_SPRING)
17+
.filter { it.isNotBlank() }
18+
.map { it.length }
19+
}
20+
.filter { it == groups }
21+
val possibilitiesCount = findSolutions(mutableMapOf(), "$text.".toList(), groups, 0)
22+
23+
private tailrec fun replaceQuestionmark(lines: Sequence<String>, count: Int): Sequence<String> {
24+
if (count > 0) {
25+
return replaceQuestionmark(
26+
lines.flatMap {
27+
listOf(
28+
it.replaceFirst(ICON_UNKNOWN_SPRING, ICON_OPERATIONAL_SPRING),
29+
it.replaceFirst(ICON_UNKNOWN_SPRING, ICON_BROKEN_SPRING)
30+
)
31+
},
32+
count - 1
33+
)
34+
}
35+
return lines
36+
}
37+
38+
@SuppressWarnings("kotlin:S6510", "kotlin:S3776")
39+
private fun findSolutions(
40+
cache: MutableMap<Triple<List<Char>, List<Int>, Int>, Long>,
41+
line: List<Char>,
42+
sizes: List<Int>,
43+
doneInGroup: Int
44+
): Long {
45+
val cv = cache[Triple(line, sizes, doneInGroup)]
46+
47+
when {
48+
cv != null -> {
49+
return cv
50+
}
51+
52+
else -> when {
53+
line.isEmpty() -> {
54+
return when {
55+
sizes.isEmpty() && (doneInGroup == 0) -> 1
56+
else -> 0
57+
}
58+
}
59+
60+
else -> {
61+
var solutions = 0L
62+
val possible = when {
63+
line[0] == ICON_UNKNOWN_SPRING -> listOf(ICON_OPERATIONAL_SPRING, ICON_BROKEN_SPRING)
64+
else -> line.subList(0, 1)
65+
}
66+
67+
for (c in possible) {
68+
when (c) {
69+
'#' -> {
70+
solutions += findSolutions(cache, line.subList(1, line.size), sizes, doneInGroup + 1)
71+
}
72+
73+
else -> {
74+
when {
75+
doneInGroup > 0 -> {
76+
when {
77+
sizes.isNotEmpty() && sizes[0] == doneInGroup -> solutions += findSolutions(
78+
cache,
79+
line.subList(1, line.size),
80+
sizes.subList(1, sizes.size),
81+
0
82+
)
83+
}
84+
}
85+
86+
else -> {
87+
solutions += findSolutions(cache, line.subList(1, line.size), sizes, 0)
88+
}
89+
}
90+
}
91+
}
92+
}
93+
94+
cache[Triple(line, sizes, doneInGroup)] = solutions
95+
return solutions
96+
}
97+
}
98+
}
99+
}
100+
}

0 commit comments

Comments
 (0)