Skip to content

Commit 7029812

Browse files
committed
Add 2023 Day 19 Part 2 solution
1 parent b094ad3 commit 7029812

File tree

1 file changed

+90
-2
lines changed

1 file changed

+90
-2
lines changed

adventofcode2023/Day19.kt

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package adventofcode2023
22

33
import java.io.File
4+
import java.util.LinkedList
45

56
object Day19 {
67
private const val ACCEPT = "A"
@@ -41,11 +42,25 @@ object Day19 {
4142

4243
private data class Condition(val variable: Char, val checker: Char, val value: Int) {
4344
fun check(checked: Map<Char, Int>): Boolean =
45+
checkValue(checked[variable]!!)
46+
47+
fun checkRange(checked: Map<Char, Pair<Int, Int>>): Int =
48+
(if (checkValue(checked[variable]!!.first)) RANGE_LOWER else 0) +
49+
(if (checkValue(checked[variable]!!.second)) RANGE_HIGHER else 0)
50+
51+
private fun checkValue(checkedValue: Int): Boolean =
4452
when (checker) {
45-
'>' -> checked[variable]!! > value
46-
'<' -> checked[variable]!! < value
53+
'>' -> checkedValue > value
54+
'<' -> checkedValue < value
4755
else -> throw Exception("Unknown checker")
4856
}
57+
58+
companion object {
59+
const val RANGE_NONE = 0
60+
const val RANGE_LOWER = 1
61+
const val RANGE_HIGHER = 2
62+
const val RANGE_BOTH = 3
63+
}
4964
}
5065

5166
private fun checkPart(part: Map<Char, Int>): Boolean {
@@ -71,9 +86,82 @@ object Day19 {
7186
throw Exception("Couldn't check part")
7287
}
7388

89+
private fun acceptedRanges(): List<Map<Char, Pair<Int, Int>>> {
90+
// Map of values (x, m, a, s), Workflow name, Workflow step index
91+
val ranges = LinkedList<Triple<Map<Char, Pair<Int, Int>>, String, Int>>()
92+
93+
val accepted = mutableListOf<Map<Char, Pair<Int, Int>>>()
94+
95+
ranges.add(Triple(mapOf(
96+
'x' to Pair(1, 4000),
97+
'm' to Pair(1, 4000),
98+
'a' to Pair(1, 4000),
99+
's' to Pair(1, 4000)
100+
), STARTING_WORKFLOW, 0))
101+
102+
while (ranges.isNotEmpty()) {
103+
val range = ranges.removeFirst()
104+
val valueRanges = range.first
105+
val workflowName = range.second
106+
val stepIndex = range.third
107+
108+
when (workflowName) {
109+
ACCEPT -> {
110+
accepted.add(valueRanges)
111+
continue
112+
}
113+
REJECT -> continue
114+
}
115+
116+
val step = workflows[workflowName]!![stepIndex]
117+
118+
if (step.first != null) {
119+
val condition = step.first!!
120+
val (variable, _, value) = condition
121+
122+
fun createTriple(
123+
changeWorkflow: Boolean, firstValue: Int = -1, secondValue: Int = -1
124+
): Triple<Map<Char, Pair<Int, Int>>, String, Int> {
125+
val newRangeMap = valueRanges.toMutableMap().apply {
126+
if (firstValue >= 0) this[variable] = this[variable]!!.copy(first = firstValue)
127+
if (secondValue >= 0) this[variable] = this[variable]!!.copy(second = secondValue)
128+
}
129+
130+
return Triple(newRangeMap, if (changeWorkflow) step.second else workflowName, if (changeWorkflow) 0 else stepIndex + 1)
131+
}
132+
133+
when (condition.checkRange(valueRanges)) {
134+
Condition.RANGE_NONE -> {
135+
ranges.add(Triple(valueRanges, workflowName, stepIndex + 1))
136+
}
137+
Condition.RANGE_LOWER -> {
138+
ranges.add(createTriple(true, secondValue = value - 1))
139+
ranges.add(createTriple(false, firstValue = value))
140+
}
141+
Condition.RANGE_HIGHER -> {
142+
ranges.add(createTriple(true, firstValue = value + 1))
143+
ranges.add(createTriple(false, secondValue = value))
144+
}
145+
Condition.RANGE_BOTH -> {
146+
ranges.add(Triple(valueRanges, step.second, 0))
147+
}
148+
}
149+
} else {
150+
ranges.add(Triple(valueRanges, step.second, 0))
151+
}
152+
}
153+
154+
return accepted
155+
}
156+
74157
fun part1() = println(parts.filter { checkPart(it) }.sumOf { it.values.sum() })
158+
159+
fun part2() = println(acceptedRanges().sumOf { ranges ->
160+
ranges.values.fold(1L) { acc, pair -> acc * (pair.second - pair.first + 1) }
161+
})
75162
}
76163

77164
fun main() {
78165
Day19.part1()
166+
Day19.part2()
79167
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy