Update solution
This commit is contained in:
parent
b636dd4c43
commit
36dc294e98
2 changed files with 59 additions and 40 deletions
|
@ -1,6 +1,6 @@
|
||||||
class Solution05(lines: List<String>) {
|
class Solution05(lines: List<String>) {
|
||||||
private var seeds: MutableList<ULong> = mutableListOf()
|
private var seeds: MutableList<ULong> = mutableListOf()
|
||||||
private var maps: MutableMap<String, Ranges> = mutableMapOf()
|
private var maps: MutableList<MapList> = mutableListOf()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
// Parse seeds
|
// Parse seeds
|
||||||
|
@ -8,24 +8,16 @@ class Solution05(lines: List<String>) {
|
||||||
seeds.addAll(seedsStr.split(" ").map{it.toULong()})
|
seeds.addAll(seedsStr.split(" ").map{it.toULong()})
|
||||||
|
|
||||||
// Parse all maps
|
// Parse all maps
|
||||||
var currentSrc = ""
|
|
||||||
for (line in lines.subList(2, lines.size)) {
|
for (line in lines.subList(2, lines.size)) {
|
||||||
if (line.isEmpty()) continue
|
if (line.isEmpty()) continue
|
||||||
|
|
||||||
if (line.contains(" map:")) {
|
if (line.contains(" map:")) {
|
||||||
val (mapTitle, _) = line.split(" ")
|
maps.add(MapList())
|
||||||
val (src, dest) = mapTitle.split("-to-")
|
|
||||||
currentSrc = src
|
|
||||||
|
|
||||||
if (!maps.containsKey(currentSrc)) {
|
|
||||||
maps[currentSrc] = Ranges(dest)
|
|
||||||
}
|
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
val (destRangeStart, srcRangeStart, rangeLength) = line.split(" ")
|
val (destRangeStart, srcRangeStart, rangeLength) = line.split(" ")
|
||||||
maps[currentSrc]?.addRange(
|
maps.last().addRange(
|
||||||
srcRangeStart.toULong(),
|
srcRangeStart.toULong(),
|
||||||
destRangeStart.toULong(),
|
destRangeStart.toULong(),
|
||||||
rangeLength.toULong(),
|
rangeLength.toULong(),
|
||||||
|
@ -33,52 +25,63 @@ class Solution05(lines: List<String>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Part 1.
|
||||||
fun getLowestLocationNumber(): ULong {
|
fun getLowestLocationNumber(): ULong {
|
||||||
return seeds
|
return seeds
|
||||||
.map{convertSeedNumber(it, "location")}
|
.map{
|
||||||
|
var num = it
|
||||||
|
|
||||||
|
for (map in maps) {
|
||||||
|
num = map.mapSrcNumberToDest(num)
|
||||||
|
}
|
||||||
|
|
||||||
|
num
|
||||||
|
}
|
||||||
.min()
|
.min()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Part 2.
|
||||||
fun getLowestLocationNumberForRangeOfSeeds(): ULong {
|
fun getLowestLocationNumberForRangeOfSeeds(): ULong {
|
||||||
val allSeeds: MutableSet<ULong> = mutableSetOf()
|
// Available location numbers.
|
||||||
|
var currentRanges = maps
|
||||||
|
.last()
|
||||||
|
.mappers
|
||||||
|
.map{RangeFromLoc(it.destRangeStart, it.rangeLength, it.destRangeStart)}
|
||||||
|
|
||||||
|
for (map in maps.reversed()) {
|
||||||
|
val newList: MutableList<RangeFromLoc> = mutableListOf()
|
||||||
|
|
||||||
|
for (mapper in map.mappers) {
|
||||||
|
// Find intersections
|
||||||
|
currentRanges
|
||||||
|
|
||||||
|
|
||||||
|
for (rng in currentRanges) {
|
||||||
|
|
||||||
for (i in 0..<seeds.size step 2) {
|
|
||||||
for (j in seeds[i]..<seeds[i]+seeds[i+1]) {
|
|
||||||
allSeeds.add(j)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return allSeeds
|
currentRanges = newList
|
||||||
.map{convertSeedNumber(it, "location")}
|
|
||||||
.min()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun convertSeedNumber(seed: ULong, target: String): ULong {
|
return 0UL
|
||||||
var dest = "seed"
|
|
||||||
|
|
||||||
var num = seed
|
|
||||||
|
|
||||||
while (dest != target) {
|
|
||||||
val ranges = maps[dest]!!
|
|
||||||
dest = ranges.destName
|
|
||||||
num = ranges.mapNumber(num)
|
|
||||||
}
|
|
||||||
|
|
||||||
return num
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Ranges(val destName: String) {
|
// Map stores the rules for matching one number to another.
|
||||||
val ranges: MutableList<Range> = mutableListOf()
|
class MapList() {
|
||||||
|
val mappers: MutableList<Mapper> = mutableListOf()
|
||||||
|
|
||||||
fun addRange(sourceRangeStart: ULong, destRangeStart: ULong, rangeLength: ULong) {
|
fun addRange(sourceRangeStart: ULong, destRangeStart: ULong, rangeLength: ULong) {
|
||||||
ranges.add(Range(sourceRangeStart, destRangeStart, rangeLength))
|
mappers.add(
|
||||||
|
Mapper(sourceRangeStart, destRangeStart, rangeLength),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun mapNumber(src: ULong): ULong {
|
fun mapSrcNumberToDest(src: ULong): ULong {
|
||||||
for (range in ranges) {
|
for (range in mappers) {
|
||||||
if (src >= range.sourceRangeStart && src < range.sourceRangeStart + range.rangeLength) {
|
if (range.isNumberInSrcRange(src)) {
|
||||||
return range.destRangeStart + src - range.sourceRangeStart
|
return range.srcValueToDest(src)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,4 +89,20 @@ data class Ranges(val destName: String) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Range(val sourceRangeStart: ULong, val destRangeStart: ULong, val rangeLength: ULong)
|
// Mapper contains one line of map.
|
||||||
|
data class Mapper(val sourceRangeStart: ULong, val destRangeStart: ULong, val rangeLength: ULong) {
|
||||||
|
fun srcValueToDest(v: ULong): ULong {
|
||||||
|
return destRangeStart + v - sourceRangeStart
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isNumberInSrcRange(num: ULong): Boolean {
|
||||||
|
return num >= sourceRangeStart && num < sourceRangeStart + rangeLength
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Range of numbers with the first number of corresponding location.
|
||||||
|
data class RangeFromLoc(val rangeStart: ULong, val rangeLength: ULong, val locationStart: ULong) {
|
||||||
|
fun getIntersection(newRangeStart: ULong, newRangeLength: ULong): RangeFromLoc {
|
||||||
|
return RangeFromLoc(rangeStart, rangeLength, locationStart)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ class Solution05Test {
|
||||||
fun solvePart1() {
|
fun solvePart1() {
|
||||||
val text = ResourceReader().readFile("day-05/input.txt")
|
val text = ResourceReader().readFile("day-05/input.txt")
|
||||||
val res = Solution05(text).getLowestLocationNumber()
|
val res = Solution05(text).getLowestLocationNumber()
|
||||||
println(res)
|
assertEquals(621354867UL, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in a new issue