From 13454b3f188c9708f5849f12d7df1b26a4fe9844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= Date: Wed, 6 Dec 2023 05:01:15 +0100 Subject: [PATCH] day5: Fix integer overflow bug --- day5/day5.kt | 62 +++++++++++++++------------------------------------- 1 file changed, 18 insertions(+), 44 deletions(-) diff --git a/day5/day5.kt b/day5/day5.kt index 234d883..249ce1a 100644 --- a/day5/day5.kt +++ b/day5/day5.kt @@ -1,6 +1,6 @@ import java.io.File -typealias Map = Pair +typealias Map = Pair fun main() { val input = File("input") @@ -13,11 +13,11 @@ fun main() { println(part2(seedRanges, maps)) } -fun part1(seeds: List, maps: List>): UInt { +fun part1(seeds: List, maps: List>): Long { return seeds.map { seed -> maps.fold(seed) { toFind, map -> findMapping(toFind, map) } }.min() } -fun findMapping(toFind: UInt, maps: List): UInt { +fun findMapping(toFind: Long, maps: List): Long { for (map in maps) { if (toFind >= map.first.first && toFind <= map.first.last) { val index = toFind - map.first.first @@ -34,50 +34,24 @@ fun findMapping(toFind: UInt, maps: List): UInt { return toFind } -fun part2(seedRanges: List, maps: List>): UInt { +fun part2(seedRanges: List, maps: List>): Long { return seedRanges .map { range -> maps .fold(listOf(range)) { toReduce, map -> findReduction(toReduce, map) } - .filter { - // TODO(tlater): Remove this cursed filter - // - // Sometimes the source and range match up - // perfectly, and the destination starts - // with 0. - // - // Maybe this is a bug in the puzzle (?!), - // or whenever this happens my logic - // breaks down and the resulting - // translated range always ends up in the - // result. - // - // Nonetheless, filtering these 0s out - // gives the right answer. - // - // More likely it's a booby trap for - // *exactly* the logical fallacy I'm - // committing? - // - // That, *or* it's just unlikely any one - // range is the lowest in the end, and - // these don't happen to contribute, while - // the rest is computed correctly. - it.first != 0u - } .map { it.first } .min() } .min() } -fun findReduction(toReduce: List, maps: List): List { - var result: MutableList = mutableListOf() - var reducing: MutableList = mutableListOf() +fun findReduction(toReduce: List, maps: List): List { + var result: MutableList = mutableListOf() + var reducing: MutableList = mutableListOf() reducing.addAll(toReduce) for (map in maps) { - var next: MutableList = mutableListOf() + var next: MutableList = mutableListOf() val source = map.first val destination = map.second @@ -96,17 +70,17 @@ fun findReduction(toReduce: List, maps: List): List { } fun getDestinationForOverlap( - overlap: UIntRange, - source: UIntRange, - destination: UIntRange -): UIntRange { + overlap: LongRange, + source: LongRange, + destination: LongRange +): LongRange { val startDiff = overlap.first - source.first val endDiff = source.last - overlap.last return destination.first + startDiff..destination.last - endDiff } -fun getOverlap(range1: UIntRange, range2: UIntRange): Pair> { +fun getOverlap(range1: LongRange, range2: LongRange): Pair> { val start = when { range1.first <= range2.first -> range2.first @@ -124,24 +98,24 @@ fun getOverlap(range1: UIntRange, range2: UIntRange): Pair end) { return Pair(null, listOf(range1)) } else { - val excess: MutableList = mutableListOf() + val excess: MutableList = mutableListOf() if (start > range1.first) { excess.add(range1.first ..< start) } if (range1.last > end) { - excess.add(end + 1u..range1.last) + excess.add(end + 1L..range1.last) } return Pair(start..end, excess) } } -fun parseInput(input: File): Pair, List>> { +fun parseInput(input: File): Pair, List>> { val text = input.bufferedReader() - val seeds = text.readLine().split(": ")[1].split(" ").map { it.toUInt() } + val seeds = text.readLine().split(": ")[1].split(" ").map { it.toLong() } text.readLine() var line = text.readLine() @@ -152,7 +126,7 @@ fun parseInput(input: File): Pair, List>> { line == "" -> Unit // Skip empty lines line.endsWith(':') -> maps.add(mutableListOf()) else -> { - val (destination, source, length) = line.split(" ").map { it.toUInt() } + val (destination, source, length) = line.split(" ").map { it.toLong() } maps.last() .add(Pair(source ..< source + length, destination ..< destination + length)) }