Skip to content

Commit 8a19305

Browse files
committed
day 10, part 2 solution
1 parent 6367475 commit 8a19305

File tree

1 file changed

+68
-14
lines changed
  • day10/src/main/kotlin/org/adventofcode

1 file changed

+68
-14
lines changed

day10/src/main/kotlin/org/adventofcode/App.kt

Lines changed: 68 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,33 +6,43 @@ data class Token(val char: Char, val pos: Int)
66

77
sealed class EvaluationResult {
88
data class Valid(val _blank: Boolean = true): EvaluationResult()
9-
data class Corrupt(val token: Token): EvaluationResult()
10-
data class Incomplete(val token: Token): EvaluationResult()
9+
data class Corrupt(val token: Token, val stack: List<Token>): EvaluationResult()
10+
data class Incomplete(val token: Token, val stack: List<Token>): EvaluationResult()
1111
data class Invalid(val token: Token): EvaluationResult()
1212
}
1313

14+
data class RepairResult(val completion: String)
15+
1416
val LEFT_BRACKET_SET = "([<{".toSet()
1517
val RIGHT_BRACKET_SET = ")]>}".toSet()
16-
val RIGHT_BRACKET_PAIRING = mapOf(
17-
')' to '(',
18-
']' to '[',
19-
'}' to '{',
20-
'>' to '<',
18+
val BRACKET_PAIRINGS = listOf(
19+
'(' to ')',
20+
'[' to ']',
21+
'{' to '}',
22+
'<' to '>',
2123
)
22-
val BRACKET_POINTS = mapOf(
24+
val LEFT_TO_RIGHT_BRACKET_MAP = BRACKET_PAIRINGS.toMap()
25+
val RIGHT_TO_LEFT_BRACKET_MAP = BRACKET_PAIRINGS.associate { it.second to it.first }
26+
val EVAL_BRACKET_POINTS = mapOf(
2327
')' to 3,
2428
']' to 57,
2529
'}' to 1197,
2630
'>' to 25137,
2731
)
32+
val REPAIR_BRACKET_POINTS = mapOf(
33+
')' to 1,
34+
']' to 2,
35+
'}' to 3,
36+
'>' to 4,
37+
)
2838

2939
object ExpressionEvaluator {
3040
fun evaluateNextToken(pos: Int, tokens: List<Token>, stack: List<Token>): EvaluationResult {
3141
if (pos == tokens.size) {
3242
val token = stack.last()
3343
return when (token.char) {
34-
in LEFT_BRACKET_SET -> EvaluationResult.Incomplete(token)
35-
in RIGHT_BRACKET_SET -> EvaluationResult.Corrupt(tokens[pos - 1])
44+
in LEFT_BRACKET_SET -> EvaluationResult.Incomplete(token, stack)
45+
in RIGHT_BRACKET_SET -> EvaluationResult.Corrupt(tokens[pos - 1], stack)
3646
else -> EvaluationResult.Valid()
3747
}
3848
}
@@ -44,8 +54,8 @@ object ExpressionEvaluator {
4454
}
4555
in RIGHT_BRACKET_SET -> {
4656
val peek = stack.lastOrNull()
47-
if (peek?.char != RIGHT_BRACKET_PAIRING[token.char]) {
48-
EvaluationResult.Corrupt(token)
57+
if (peek?.char != RIGHT_TO_LEFT_BRACKET_MAP[token.char]) {
58+
EvaluationResult.Corrupt(token, stack)
4959
} else {
5060
evaluateNextToken(pos + 1, tokens, stack.dropLast(1))
5161
}
@@ -62,6 +72,18 @@ object ExpressionEvaluator {
6272
}
6373
}
6474

75+
object IncompleteExpressionRepairer {
76+
fun buildCompletionString(stack: List<Token>, expr: String = ""): String {
77+
if (stack.isEmpty()) {
78+
return expr;
79+
}
80+
81+
val token = stack.last()
82+
val currentExpr = expr + LEFT_TO_RIGHT_BRACKET_MAP[token.char]
83+
return buildCompletionString(stack.dropLast(1), currentExpr)
84+
}
85+
}
86+
6587
fun runSolutionPart1(expressions: List<String>) {
6688
val evaluations = expressions.map { it to ExpressionEvaluator.evaluate(it) }
6789

@@ -75,12 +97,44 @@ fun runSolutionPart1(expressions: List<String>) {
7597
.groupingBy { it.token.char }
7698
.eachCount()
7799
.toList()
78-
.sumOf { (char, count) -> count * BRACKET_POINTS[char]!! }
100+
.sumOf { (char, count) -> count * EVAL_BRACKET_POINTS[char]!! }
79101

80102
println("\nPoints = $points")
81103
}
82104

105+
fun runSolutionPart2(expressions: List<String>) {
106+
val evaluations = expressions.map { it to ExpressionEvaluator.evaluate(it) }
107+
108+
val repairs = evaluations
109+
.filter { (_, result) -> result is EvaluationResult.Incomplete }
110+
.map { (expr, result) ->
111+
val stack = (result as EvaluationResult.Incomplete).stack
112+
expr to IncompleteExpressionRepairer.buildCompletionString(stack)
113+
}
114+
115+
val sumPointsForRepair: (String) -> Long = { repair: String ->
116+
repair.toList().fold(0L) { points, bracket ->
117+
(points * 5) + REPAIR_BRACKET_POINTS[bracket]!!
118+
}
119+
}
120+
121+
println()
122+
123+
val scoredRepairs = repairs
124+
.map { (expr, repair) -> repair to sumPointsForRepair(repair) }
125+
.sortedBy { (_, points) -> points }
126+
127+
scoredRepairs.forEach { (repair, points) ->
128+
println("repair $repair: points = $points")
129+
}
130+
131+
val middleScoredReport = scoredRepairs[scoredRepairs.size / 2]
132+
133+
println("\nMiddle: $middleScoredReport")
134+
}
135+
83136
fun main() {
84137
val expressions = File("day10/src/main/resources/puzzleInput.txt").readLines()
85-
runSolutionPart1(expressions)
138+
// runSolutionPart1(expressions)
139+
runSolutionPart2(expressions)
86140
}

0 commit comments

Comments
 (0)