Skip to content

Commit

Permalink
Day21
Browse files Browse the repository at this point in the history
  • Loading branch information
elizarov committed Dec 21, 2022
1 parent acd6691 commit a742a56
Show file tree
Hide file tree
Showing 2 changed files with 2,482 additions and 0 deletions.
131 changes: 131 additions & 0 deletions src/Day21.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
fun main() {
day21Part(1)
day21Part(2)
}

private const val ROOT = "root"
private const val HUMN = "humn"

fun day21Part(part: Int) {
val dayId = "21"
val input = readInput("Day${dayId}")

data class Monkey(val name: String, var x: Long?, val a: String, var op: String, val b: String)

val ms = input.map { s ->
val (name, os) = s.split(": ")
val x = os.toLongOrNull()
if (x != null) {
Monkey(name, x, "", "", "")
} else {
val (a, op, b) = os.split(" ")
Monkey(name, null, a, op, b)
}
}.associateBy { it.name }

if (part == 2) {
ms[HUMN]!!.x = null
ms[ROOT]!!.op = "="
}

fun compute(name: String): Long? {
val m = ms[name]!!
if (m.name == HUMN || m.x != null) return m.x
val av = compute(m.a)
val bv = compute(m.b)
if (av == null || bv == null) return null
val x = when (m.op) {
"+" -> av + bv
"-" -> av - bv
"*" -> av * bv
"/" -> av / bv
else -> error(m.op)
}
m.x = x
return x
}

val ans1 = compute(ROOT)

if (part == 1) {
println("part1 = $ans1")
return
}

var r = ROOT
var c = 0L
while (r != HUMN) {
val m = ms[r]!!
val a = ms[m.a]!!
val b = ms[m.b]!!
when (m.op) {
"=" -> when {
a.x != null -> {
check(b.x == null)
r = m.b
c = a.x!!
}
b.x != null -> {
check(a.x == null)
r = m.a
c = b.x!!
}
else -> error(m)
}
"+" -> when {
a.x != null -> {
check(b.x == null)
r = m.b
c -= a.x!!
}
b.x != null -> {
check(a.x == null)
r = m.a
c -= b.x!!
}
else -> error(m)
}
"-" -> when {
a.x != null -> {
check(b.x == null) { "$m" }
r = m.b
c = a.x!! - c
}
b.x != null -> {
check(a.x == null)
r = m.a
c += b.x!!
}
else -> error(m)
}
"*" -> when {
a.x != null -> {
check(b.x == null)
r = m.b
c /= a.x!!
}
b.x != null -> {
check(a.x == null)
r = m.a
c /= b.x!!
}
else -> error(m)
}
"/" -> when {
a.x != null -> {
check(b.x == null)
r = m.b
c = a.x!! / c
}
b.x != null -> {
check(a.x == null)
r = m.a
c *= b.x!!
}
else -> error(m)
}
else -> error(m)
}
}
println("part2 = $c")
}
Loading

0 comments on commit a742a56

Please sign in to comment.