From d12618febd336223defc1a18a83f2276667c9579 Mon Sep 17 00:00:00 2001 From: Hubert Van De Walle Date: Sun, 13 Dec 2020 11:39:40 +0100 Subject: [PATCH] Day13 --- days/src/main/kotlin/Day13.kt | 55 +++++++++++++++++++++++++++++++ days/src/main/resources/day13.txt | 2 ++ days/src/test/kotlin/Day13Test.kt | 27 +++++++++++++++ 3 files changed, 84 insertions(+) create mode 100644 days/src/main/kotlin/Day13.kt create mode 100644 days/src/main/resources/day13.txt create mode 100644 days/src/test/kotlin/Day13Test.kt diff --git a/days/src/main/kotlin/Day13.kt b/days/src/main/kotlin/Day13.kt new file mode 100644 index 0000000..87a7a48 --- /dev/null +++ b/days/src/main/kotlin/Day13.kt @@ -0,0 +1,55 @@ +package be.vandewalleh.aoc.days + +import be.vandewalleh.aoc.utils.input.Day +import be.vandewalleh.aoc.utils.input.Input +import be.vandewalleh.aoc.utils.input.Lines +import be.vandewalleh.aoc.utils.input.createDay +import kotlin.math.abs + +data class Bus(val index: Int, val id: Long) + +@Day(13) +class Day13(@Lines val input: Input>) { + + fun part1(): Int { + val id = input.value[0].toInt() + + val (busId, min) = input.value[1] + .splitToSequence(",") + .filterNot { it == "x" } + .map { it.toInt() } + .map { bus -> bus to id / bus } + .map { (bus, div) -> bus to bus * (div + 1) } + .minByOrNull { it.second }!! + + return busId * abs(min - id) + } + + private tailrec fun gcd(a: Long, b: Long): Long = if (b == 0L) a else gcd(b, a % b) + private fun lcm(a: Long, b: Long): Long = a / gcd(a, b) * b + + fun part2(): Long { + val buses = input.value[1] + .splitToSequence(",") + .mapIndexedNotNull { index, bus -> + if (bus == "x") null + else Bus(index, bus.toLong()) + } + .toList() + + var step = 1L + var t = 0L + + for ((i, id) in buses) { + while ((t + i) % id != 0L) t += step + step = lcm(step, id) + } + + return t + } +} + +fun main() = with(createDay()) { + println(part1()) + println(part2()) +} diff --git a/days/src/main/resources/day13.txt b/days/src/main/resources/day13.txt new file mode 100644 index 0000000..d55b7ca --- /dev/null +++ b/days/src/main/resources/day13.txt @@ -0,0 +1,2 @@ +1000511 +29,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,37,x,x,x,x,x,409,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,17,13,19,x,x,x,23,x,x,x,x,x,x,x,353,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,41 diff --git a/days/src/test/kotlin/Day13Test.kt b/days/src/test/kotlin/Day13Test.kt new file mode 100644 index 0000000..3b19981 --- /dev/null +++ b/days/src/test/kotlin/Day13Test.kt @@ -0,0 +1,27 @@ +package be.vandewalleh.aoc.days + +import be.vandewalleh.aoc.utils.input.Input +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.CsvSource + +class Day13Test { + + @CsvSource( + value = [ + " 7,13 | 77", + " 17,x,13,19 | 3417", + " 67,7,59,61 | 754018", + " 67,x,7,59,61 | 779210", + " 67,7,x,59,61 | 1261476", + "1789,37,47,1889 | 1202161486", + ], + delimiter = '|' + ) + @ParameterizedTest + fun examples(buses: String, answer: Long) { + val input = Input(listOf("", buses)) + assertThat(Day13(input).part2()).isEqualTo(answer) + } + +}