Skip to content

Instantly share code, notes, and snippets.

@bsautner
Created December 11, 2022 18:54
Show Gist options
  • Save bsautner/a4f153869d45e2b5c26f06f5d24b6f9b to your computer and use it in GitHub Desktop.
Save bsautner/a4f153869d45e2b5c26f06f5d24b6f9b to your computer and use it in GitHub Desktop.
AOC11.kt
import java.io.File
import java.math.BigDecimal
class AOC11 {
private val rounds = 20
private val monkeys = mutableListOf<Monkey>()
private val monkeys2 = mutableListOf<Monkey2>()
fun process() {
// val input = File("/home/ben/aoc/input-11.txt")
val input = File("/home/ben/aoc/sample.txt")
val split = input.readText().split("\n\n")
split.forEach {
val data = it.split("\n")
val startingItems = createListOfIntegers(data[1].replace(" Starting items: ", ""))
println()
val ops = data[2].trim().split(" ")
val operator = ops[4]
val valueCheck = ops[5]
val value: BigDecimal? = if (valueCheck == "old") {
null
} else {
BigDecimal.valueOf(valueCheck.toLong())
}
val testCheck = data[3].trim().split(" ")
val test = testCheck[3].toLong()
val trueMonkey = data[4].trim().split(" ")[5].toInt()
val falseMonkey = data[5].trim().split(" ")[5].toInt()
val bigTest = BigDecimal.valueOf(test)
monkeys.add(Monkey(startingItems, operator, value, bigTest, trueMonkey, falseMonkey))
}
doWork()
//part2
val input2 = File("/home/ben/aoc/input-11.txt")
val sample2 = input2.useLines { it.toList() }
var m = sample2.chunked(7).map { Monkey2.parseMonkeyData(it) }
monkeys2.addAll(m)
val testProduct: Long = monkeys2.map { it.test }.reduce(Long::times)
rounds(10_000) { it % testProduct }
println("Part2: ${monkeys2.business()}")
}
private fun doWork() {
(1..rounds).forEach { round ->
println(round)
monkeys.forEach { monkey ->
while (monkey.startingItems.isNotEmpty()) {
inspect(monkey)
}
}
}
println("After Round $rounds")
for (i in 0 until monkeys.size) {
println("Monkey $i inspected items ${monkeys[i].inspections} times.")
}
monkeys.sortBy {
it.inspections
}
monkeys.reverse()
println(monkeys[0].inspections * monkeys[1].inspections)
println()
}
private fun inspect(monkey: Monkey) {
val item = monkey.startingItems.removeFirst()
val worryLevel: BigDecimal
monkey.inspections = monkey.inspections + 1
val o: BigDecimal = monkey.worryLevelOperatorValue ?: item
worryLevel = when (monkey.worryLevelOperator) {
"*" -> {
item.multiply(o)
}
"+" -> {
item.add(o)
}
else -> {
throw IllegalStateException()
}
}
if (worryLevel.remainder(monkey.test) != BigDecimal.ZERO) {
monkeys[monkey.falseMonkey].startingItems.add(worryLevel)
} else {
monkeys[monkey.trueMonkey].startingItems.add(worryLevel)
}
}
fun createListOfIntegers(input: String): MutableList<BigDecimal> {
val numbersAsStrings = input.split(", ")
return numbersAsStrings.map { BigDecimal.valueOf(it.toLong())}.toMutableList()
}
private fun List<Monkey2>.business(): Long = sortedByDescending { it.interactions }.let { it[0].interactions * it[1].interactions }
private fun rounds(numRounds: Int, changeToWorryLevel: (Long) -> Long) {
repeat(numRounds) {
monkeys2.forEach { it.inspectItems(monkeys2, changeToWorryLevel) }
}
}
/**
* Monkey 0:
Starting items: 65, 58, 93, 57, 66
Operation: new = old * 7
Test: divisible by 19
If true: throw to monkey 6
If false: throw to monkey 4
*/
private class Monkey(
val startingItems: MutableList<BigDecimal>,
val worryLevelOperator: String,
val worryLevelOperatorValue: BigDecimal?,
val test: BigDecimal,
val trueMonkey: Int,
val falseMonkey: Int
) {
var inspections = 0L
}
private class Monkey2(
val items: MutableList<Long>,
val operation: (Long) -> Long,
val test: Long,
val trueMonkey: Int,
val falseMonkey: Int
) {
var interactions: Long = 0
fun inspectItems(monkeys: List<Monkey2>, changeToWorryLevel: (Long) -> Long) {
items.forEach { item ->
val worry = changeToWorryLevel(operation(item))
val target = if (worry % test == 0L) trueMonkey else falseMonkey
monkeys[target].items.add(worry)
}
interactions += items.size
items.clear()
}
companion object {
fun parseMonkeyData(input: List<String>): Monkey2 {
val items = input[1].substringAfter(": ").split(", ").map { it.toLong() }.toMutableList()
val operationValue = input[2].substringAfterLast(" ")
val operation: (Long) -> Long = when {
operationValue == "old" -> ({ it * it })
'*' in input[2] -> ({ it * operationValue.toLong() })
else -> ({ it + operationValue.toLong() })
}
val test = input[3].substringAfterLast(" ").toLong()
val trueMonkey = input[4].substringAfterLast(" ").toInt()
val falseMonkey = input[5].substringAfterLast(" ").toInt()
return Monkey2(
items,
operation,
test,
trueMonkey,
falseMonkey
)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment