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()) }