Advent of Code 2021 day 11
12/11/2022, 5:00 AMxxfast
12/11/2022, 5:41 AMBin Wang
12/11/2022, 5:48 AMxxfast
12/11/2022, 5:48 AMMarcin Wisniowski
12/11/2022, 5:50 AMHayden Meloche
12/11/2022, 6:05 AMinput.removeAll { it.isBlank() }
input.windowed(size = 6, step = 6)
helped a lot for me parsing the inputDavid Whittaker
12/11/2022, 6:05 AMKai Yuan
12/11/2022, 6:08 AMJonathan Kolberg
12/11/2022, 6:08 AMVlad Petrushkevich
12/11/2022, 6:11 AMEvegenii Khokhlov
12/11/2022, 6:13 AMJonathan Kolberg
12/11/2022, 6:17 AMEvegenii Khokhlov
12/11/2022, 6:24 AMBrian Hartvigsen
12/11/2022, 6:25 AMHayden Meloche
12/11/2022, 6:26 AMBrian Hartvigsen
12/11/2022, 6:26 AMJacob
12/11/2022, 6:26 AMJacob
12/11/2022, 6:26 AMJonathan Kolberg
12/11/2022, 6:27 AMHayden Meloche
12/11/2022, 6:28 AMBrian Hartvigsen
12/11/2022, 6:28 AMHayden Meloche
12/11/2022, 6:28 AMJonathan Kolberg
12/11/2022, 6:30 AMbabel
12/11/2022, 6:30 AMBrian Hartvigsen
12/11/2022, 6:30 AMBrian Hartvigsen
12/11/2022, 6:31 AMBrian Hartvigsen
12/11/2022, 6:32 AMJacob Moulton
12/11/2022, 6:32 AMJonathan Kolberg
12/11/2022, 6:33 AMBrian Hartvigsen
12/11/2022, 6:33 AMHayden Meloche
12/11/2022, 6:34 AMNeil Banman
12/11/2022, 6:35 AMNeil Banman
12/11/2022, 6:36 AMBrian Hartvigsen
12/11/2022, 6:42 AMinput.lines().chunked(7).forEach {
and then reading the necessary into a class I created made it work. ๐Jonathan Kolberg
12/11/2022, 6:42 AMBrian Hartvigsen
12/11/2022, 6:46 AMHayden Meloche
12/11/2022, 6:47 AMSergei Petunin
12/11/2022, 6:50 AMJacob
12/11/2022, 6:55 AMJonathan Kolberg
12/11/2022, 6:55 AMMichael de Kaste
12/11/2022, 6:58 AMobject Day11 : Challenge() {
class Monkey(
val inspection: (Long) -> Long,
val testNumber: Long,
private val ifTrue: Int,
private val ifFalse: Int
) {
fun throwTarget(number: Long) = if (number % testNumber == 0L) ifTrue else ifFalse
}
val parsed = input.split(System.lineSeparator() + System.lineSeparator()).map {
it.lines().drop(1).let { (a, b, c, d, e) ->
Monkey(
inspection = b.substringAfter("old ").split(" ")
.let { (type, value) -> (type == "+") to value.toLongOrNull() }
.let { (isAdd, long) -> if (isAdd) { x -> x + (long ?: x) } else { x -> x * (long ?: x) } },
testNumber = c.substringAfter("by ").toLong(),
ifTrue = d.substringAfter("monkey ").toInt(),
ifFalse = e.substringAfter("monkey ").toInt()
) to a.substringAfter(": ").split(", ").map(String::toLong)
}
}.unzip()
private val monkeys = parsed.first
private val initialItems = parsed.second
private fun solve(times: Int, worryMitigation: (Long) -> Long): Long {
val inspections = LongArray(monkeys.size)
val itemsToTrack = initialItems.map { it.toMutableList() }
repeat(times) {
for ((index, monkey) in monkeys.withIndex()) {
inspections[index] = inspections[index] + itemsToTrack[index].size
for (item in itemsToTrack[index]) {
val monkeyDoInspection = worryMitigation(monkey.inspection(item))
itemsToTrack[monkey.throwTarget(monkeyDoInspection)] += monkeyDoInspection
}
itemsToTrack[index].clear()
}
}
return inspections.sortedDescending().let { (a, b) -> a * b }
}
override fun part1() = solve(20) { it / 3 }
override fun part2() = solve(10_000) { it % monkeys.map(Monkey::testNumber).reduce(Long::times) }
}
Michael de Kaste
12/11/2022, 6:58 AMnkiesel
12/11/2022, 7:00 AMJan Durovec
12/11/2022, 7:01 AMMichael de Kaste
12/11/2022, 7:02 AMnkiesel
12/11/2022, 7:03 AMMichael de Kaste
12/11/2022, 7:03 AMJonathan Kolberg
12/11/2022, 7:03 AMJan Durovec
12/11/2022, 7:05 AMJohannes Gรคtjen
12/11/2022, 7:06 AMnew = old * old
? unless I'm missing something this means Long is necessary. it would be pretty unfair if for some inputs it works with just Int and for others it doesn't.Jonathan Kolberg
12/11/2022, 7:07 AMBrian Hartvigsen
12/11/2022, 7:07 AMJan Durovec
12/11/2022, 7:08 AMJonathan Kolberg
12/11/2022, 7:08 AMJonathan Kolberg
12/11/2022, 7:08 AMJan Durovec
12/11/2022, 7:15 AMLong
is necessary and it doesn't work with just Int
(for the worry level; the inspection counters can be Int
)Neil Banman
12/11/2022, 7:18 AMDan Fingal-Surma
12/11/2022, 7:29 AMDan Fingal-Surma
12/11/2022, 7:29 AMDan Fingal-Surma
12/11/2022, 7:34 AMSergei Petunin
12/11/2022, 7:46 AMDan Fingal-Surma
12/11/2022, 7:49 AMJonathan Kolberg
12/11/2022, 7:50 AMxxfast
12/11/2022, 7:52 AMThe clue you'll need to find another way to keep your worry levels manageable.is a very subtle clue.
Jintin
12/11/2022, 7:53 AMCognitive Gear
12/11/2022, 8:08 AMDan Fingal-Surma
12/11/2022, 8:08 AMEvegenii Khokhlov
12/11/2022, 8:49 AMLong
is necessary to perform computations. but actual worry level never overflow Int
. That was my pointritesh
12/11/2022, 9:09 AMephemient
12/11/2022, 9:09 AMephemient
12/11/2022, 9:11 AMlcm
but Eric fairly obviously only gave us prime divisors so there isn't really a needโฆJonathan Kolberg
12/11/2022, 9:14 AMKarloti
12/11/2022, 9:17 AMxxfast
12/11/2022, 9:21 AMKarloti
12/11/2022, 9:21 AMphldavies
12/11/2022, 9:39 AMJakub Gwรณลบdลบ
12/11/2022, 9:43 AMlong
, otherwise, nah.Riccardo Lippolis
12/11/2022, 9:54 AMritesh
12/11/2022, 9:58 AMritesh
12/11/2022, 10:24 AM%
it with worryLevel
Karloti
12/11/2022, 10:51 AMDavio
12/11/2022, 10:51 AMDavio
12/11/2022, 10:52 AMDavio
12/11/2022, 10:53 AMGrzegorz Aniol
12/11/2022, 10:57 AMPoisonedYouth
12/11/2022, 11:20 AMJakub Gwรณลบdลบ
12/11/2022, 11:28 AM3 mod 10
is the same as 13 mod 10
, as 23 mod 10
and 123456789012345678903 mod 10
๐Davio
12/11/2022, 11:32 AMAnirudh
12/11/2022, 11:56 AMold
being possibly repeated. and I didn't want to hardcode the rules (even if only 4 or 7)
fun String.toOperation(): (Long) -> Long {
...
return { old: Long -> operator(arg1 ?: old, arg2 ?: old) }
}
โข also, it's only created once per monkey at inputParse
time rather than at every round or every item in the monkeys list
โข really wanted a monkey.see().monkeyDo()
in my code ๐ but without global state, the closest I could come to it was:
monkey.see().map { monkey.`do`(it) }
โฆ which also makes me happyAnirudh
12/11/2022, 11:56 AMJan Durovec
12/11/2022, 11:57 AMMonkey
class so that it is updated as necessary when new Monkey
is instantiated. The documentation says that the Kotlin equivalent of static field is companion object
however, if I try to apply it to my class, I get an error saying that "Modifier 'companion' is not applicable inside 'local class'". I could move the Monkey
class out of fun main()
(and then the error disappears) but that would pollute the global package/namespace with my class. Is there some way how to declare "private static" field in a class that is local to a function (main
in this case) in Kotlin?Adam S
12/11/2022, 11:59 AM// src/kotlin/main.kt
private class Monkey {
companion object { }
}
fun main() { }
Jan Durovec
12/11/2022, 12:00 PMfun main
?Jan Durovec
12/11/2022, 12:03 PMephemient
12/11/2022, 12:05 PMAdam S
12/11/2022, 12:06 PMJan Durovec
12/11/2022, 12:06 PMDavio
12/11/2022, 12:17 PMDavio
12/11/2022, 12:22 PMrkechols
12/11/2022, 12:43 PMJohannes Gรคtjen
12/11/2022, 12:44 PMJohannes Gรคtjen
12/11/2022, 12:48 PMobject DayXX {
fun part1(input: Lsit<String>): Int {
// do stuff
return result
}
// ... all the other functions and classes to solve it
}
fun main() {
readInput("resources/dayXX")
println(DayXX.part1(input))
}
PoisonedYouth
12/11/2022, 12:50 PMJoakim Tall
12/11/2022, 1:29 PMJoakim Tall
12/11/2022, 1:30 PMJoakim Tall
12/11/2022, 1:31 PMJoakim Tall
12/11/2022, 1:31 PMJoakim Tall
12/11/2022, 1:47 PMJoakim Tall
12/11/2022, 2:16 PMCharles Flynn
12/11/2022, 2:26 PMMarcin Wisniowski
12/11/2022, 2:40 PMMarcin Wisniowski
12/11/2022, 2:44 PMCharles Flynn
12/11/2022, 2:57 PMHayden Meloche
12/11/2022, 2:58 PMMarcin Wisniowski
12/11/2022, 3:00 PMFredrik Rรธdland
12/11/2022, 3:00 PMCharles Flynn
12/11/2022, 3:02 PMphldavies
12/11/2022, 5:00 PMAnirudh
12/11/2022, 5:34 PMDavio
12/11/2022, 5:39 PM@JvmInline
value class MyInt(private val i: Int) {
operator fun times(other: MyInt): MyInt {
if (i == 0 || other.i == 0) return MyInt(0)
var result = 0
repeat(other.i.absoluteValue) {
if (this.i.sign != other.i.sign) {
result -= this.i.absoluteValue
} else if (this.i.sign == 1 && other.i.sign == 1) {
result += this.i
} else {
result -= this.i
}
if (this.i.sign != other.i.sign && result.sign != -1) throw ArithmeticException()
if (this.i.sign == 1 && other.i.sign == 1 && result.sign == -1) throw ArithmeticException()
if (this.i.sign == -1 && other.i.sign == -1 && result.sign == -1) throw ArithmeticException()
}
return MyInt(result)
}
}
fun main() {
println(MyInt(5) * MyInt(7))
println(MyInt(5) * MyInt(-7))
println(MyInt(-7) * MyInt(5))
println(MyInt(-5) * MyInt(-7))
println(MyInt(Int.MAX_VALUE - 1) * MyInt(2))
}
This example uses repeated addition / subtraction to implement multiplication and watches for changes to the sign, if the sign changes other than what it expects (it expects pos * pos -> pos, neg * neg -> pos and the others to yield a negative answer) then it assumes the value has wrapped around and throws an exception.
I'm using absolute values here, so Int.MIN_VALUE being its own absolute value probably screws this up, but I just wanted to make a fun demo. ๐todd.ginsberg
12/11/2022, 5:46 PMFilip Wiesner
12/11/2022, 6:26 PMNeil Banman
12/11/2022, 6:27 PMLuke Armitage
12/11/2022, 6:27 PMphldavies
12/11/2022, 6:28 PMFilip Wiesner
12/11/2022, 6:29 PMDan Fingal-Surma
12/11/2022, 6:33 PMFilip Wiesner
12/11/2022, 6:34 PMritesh
12/11/2022, 6:41 PMmod
part of it, in today's problem. I also saw few folks not using mod
. I wonder if some other maths trick is involved apart from this one.Luke Armitage
12/11/2022, 7:45 PMOlaf Gottschalk
12/11/2022, 8:11 PMPaul Woitaschek
12/11/2022, 9:45 PMchiroptical
12/12/2022, 12:05 AMchiroptical
12/12/2022, 12:13 AMNeil Banman
12/12/2022, 1:25 AMchiroptical
12/12/2022, 1:26 AMNeil Banman
12/12/2022, 1:27 AMchiroptical
12/12/2022, 1:28 AMephemient
12/12/2022, 1:30 AMephemient
12/12/2022, 1:31 AMNeil Banman
12/12/2022, 4:00 AMimport kotlin.collections.fold as luv
...
val me = inspections.apply { sortDescending() }.take(2)
val u = 1L
return me.luv(u, Long::times)
Abdul Khaliq
12/12/2022, 9:59 AMLuke Armitage
12/12/2022, 10:04 AMAbdul Khaliq
12/12/2022, 10:04 AMephemient
12/12/2022, 10:12 AMphldavies
12/12/2022, 10:14 AMMarcin Wisniowski
12/12/2022, 10:15 AMMichael Bรถiers
12/13/2022, 9:15 PMpackage aoc2022
fun main() {
data class Item(private val initial: Int, private val remainders: Map<Int, Int>) {
fun rem(d: Int, useInitial: Boolean) = 0 == if (useInitial) (initial % d) else remainders.getValue(d)
fun transform(op: (Int) -> Int) = Item(op(initial), remainders.toMutableMap().apply {
keys.forEach { prime -> set(prime, op(getValue(prime)) % prime) }
})
}
fun Int.toItem() = Item(this, buildMap {
for (prime in listOf(2, 3, 5, 7, 9, 11, 13, 17, 19, 23)) set(prime, this@toItem % prime)
})
data class Monkey(val items: MutableList<Item>, val operation: (Item) -> Item, val test: Triple<Int, Int, Int>) {
fun test(item: Item, useInitial: Boolean) = if (item.rem(test.first, useInitial)) test.second else test.third
}
val input = System.`in`.reader().readText()
fun doMonkeyBusiness(rounds: Int, div: Boolean): Long {
val monkeys = input.split("\n\n").map { it.split("\n") }.map { lines ->
val items = lines[1].split(" ", ",").mapNotNull(String::toIntOrNull).map { it.toItem() }.toMutableList()
val opChar = lines[2][lines[2].lastIndexOf(" ") - 1]
val operand = lines[2].substringAfterLast(" ").toIntOrNull()
val operation: (Item) -> Item = when {
opChar == '+' -> { old -> old.transform { it + operand!! } }
operand != null -> { old -> old.transform { it * operand } }
else -> { old -> old.transform { it * it } }
}
val divBy = lines[3].split(" ").mapNotNull(String::toIntOrNull).single()
val ifTrue = lines[4].split(" ").mapNotNull(String::toIntOrNull).single()
val ifFalse = lines[5].split(" ").mapNotNull(String::toIntOrNull).single()
Monkey(items, operation, Triple(divBy, ifTrue, ifFalse))
}
val inspections = LongArray(monkeys.size) { 0 }
repeat(rounds) {
for ((i, monkey) in monkeys.withIndex()) with(monkey) {
inspections[i] = inspections[i] + items.size
for (item in items) operation(item)
.let { newItem -> if (div) newItem.transform { it / 3 } else newItem }
.also { monkeys[test(it, div)].items += it }
items.clear()
}
}
return inspections.sortedDescending().take(2).reduce(Long::times)
}
listOf(doMonkeyBusiness(20, true), doMonkeyBusiness(10_000, false)).forEach(::println)
}
ephemient
12/14/2022, 4:44 AMyou'll need to find another way to keep your worry levels manageableis the important hint in the text
ephemient
12/14/2022, 4:45 AM