Created
December 11, 2022 18:54
-
-
Save bsautner/a4f153869d45e2b5c26f06f5d24b6f9b to your computer and use it in GitHub Desktop.
AOC11.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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