From e720bbecdbafa15584537da9adf7a85e9d91cfce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20R=C3=B8dland?= Date: Fri, 15 Dec 2023 10:38:20 +0100 Subject: [PATCH] 2023 - Day 15 - part 2 --- .../kotlin/no/rodland/advent_2023/Day15.kt | 53 ++++++++++++++++--- .../no/rodland/advent_2023/Day15Test.kt | 4 +- 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/src/main/kotlin/no/rodland/advent_2023/Day15.kt b/src/main/kotlin/no/rodland/advent_2023/Day15.kt index d8f0abac..14debf32 100644 --- a/src/main/kotlin/no/rodland/advent_2023/Day15.kt +++ b/src/main/kotlin/no/rodland/advent_2023/Day15.kt @@ -5,24 +5,63 @@ import no.rodland.advent.Day // template generated: 15/12/2023 // Fredrik Rødland 2023 -class Day15(val input: List) : Day> { +class Day15(val input: List) : Day> { private val parsed = input.parse() override fun partOne(): Int { - return parsed.sumOf { it.hash() } + return parsed.sumOf { it.hash } } - private fun CharArray.hash() = fold(0) { acc, c -> ((c.code + acc) * 17).mod(256) } + override fun partTwo(): Int { + val ar = Array(256) { mutableListOf() } + parsed.forEach { step -> + ar[step.label.hash()].also { box -> + if (step.isMinus) { + box.remove(step.label) + } else { + box.replace(step.label, step) + } + } + } + return ar.flatMapIndexed { idx, list -> + list.mapIndexed { listIdx, lens -> focusingPower(idx, listIdx, lens) } + }.sum() + } + + private fun focusingPower(boxIndex: Int, lensIndex: Int, lens: Lens) = (boxIndex + 1) * (lensIndex + 1) * lens.focal + + private fun MutableList.remove(label: String) { + removeAll { it.label == label } + } - override fun partTwo(): Long { - return 2 + private fun MutableList.replace(label: String, step: Step) { + Lens(label, step.num!!).also { lens -> + indexOfFirst { it.label == label }.also { if (it >= 0) this[it] = lens else add(lens) } + } } - override fun List.parse(): List { - return first().split(",").map { it.toCharArray() } + data class Lens(val label: String, val focal: Int) + + data class Step(val str: String) { + val label = str.split("=", "-")[0] + val num: Int? = str.split("=").let { + if (it.size == 2) { + it[1].toInt() + } else { + null + } + } + val isMinus = num == null + val hash = str.hash() + } + + override fun List.parse(): List { + return first().split(",").map { Step(it) } } override val day = "15".toInt() } +fun String.hash() = fold(0) { acc, c -> ((c.code + acc) * 17).mod(256) } + diff --git a/src/test/kotlin/no/rodland/advent_2023/Day15Test.kt b/src/test/kotlin/no/rodland/advent_2023/Day15Test.kt index 6bcd5a6b..56814890 100644 --- a/src/test/kotlin/no/rodland/advent_2023/Day15Test.kt +++ b/src/test/kotlin/no/rodland/advent_2023/Day15Test.kt @@ -16,9 +16,9 @@ internal class Day15Test { private val test15 = "2023/input_15_test.txt".readFile() private val resultTestOne = 1320 - private val resultTestTwo = 2L + private val resultTestTwo = 145 private val resultOne = 522547 - private val resultTwo = 2L + private val resultTwo = 229271 val test = defaultTestSuiteParseOnInit( Day15(data15),