Advent of Code 2023 day 5
12/05/2023, 5:00 AMKroppeb
12/05/2023, 5:13 AMKroppeb
12/05/2023, 5:40 AMJonathan Kolberg
12/05/2023, 6:12 AMAnirudh
12/05/2023, 6:35 AMAnirudh
12/05/2023, 6:40 AMephemient
12/05/2023, 6:41 AMMichael de Kaste
12/05/2023, 6:52 AMMarcin Wisniowski
12/05/2023, 6:53 AMxxfast
12/05/2023, 7:02 AMPeter Duong
12/05/2023, 7:02 AMPeter Duong
12/05/2023, 7:03 AMPeter Duong
12/05/2023, 7:04 AMxxfast
12/05/2023, 7:05 AM4m 49.512857667s
- is that about the same time it took you with your trick?Marcin Wisniowski
12/05/2023, 7:05 AMMarcin Wisniowski
12/05/2023, 7:05 AMNorbert Kiesel
12/05/2023, 7:08 AMPeter Duong
12/05/2023, 7:08 AMPeter Duong
12/05/2023, 7:09 AMMarcin Wisniowski
12/05/2023, 7:10 AMxxfast
12/05/2023, 7:10 AM4m 49.512857667s
crapxxfast
12/05/2023, 7:10 AMNorbert Kiesel
12/05/2023, 7:13 AMNikita Merinov
12/05/2023, 7:16 AMJohannes GΓ€tjen
12/05/2023, 7:22 AMMarcin Wisniowski
12/05/2023, 7:26 AMNorbert Kiesel
12/05/2023, 7:32 AMNorbert Kiesel
12/05/2023, 7:35 AMKroppeb
12/05/2023, 7:35 AMMarcin Wisniowski
12/05/2023, 7:43 AMMarcin Wisniowski
12/05/2023, 7:44 AMritesh
12/05/2023, 7:47 AMMarcin Wisniowski
12/05/2023, 7:48 AMJan Durovec
12/05/2023, 7:49 AMfun Iterable<IntRange>.union(): List<IntRange>
in my utils class but today I need fun Iterable<LongRange>.union(): List<LongRange>
. Since IntRange
and LongRange
don't have any common predecessor (or do they? maybe I could use ClosedRange
) it seems that I need to have the same code duplicated in my utils. However, even after duplicating the function, during (JVM) compilation I'm getting Platform declaration clash: The following declarations have the same JVM signature (union(Ljava/lang/Iterable;)Ljava/util/List;)
. Is there some way how to create a union
function that works for both IntRange
and LongRange
? I.e. ideally by declaring it so that it can work with both (and returns corresponding type) or declaring it twice without compilation signature conflict?Nikita Merinov
12/05/2023, 7:52 AMClosedRange
seems to be good. Was there any issues with that?Jan Durovec
12/05/2023, 7:56 AMClosedRange
only accepts Comparable
). But I'm not sure about T : ClosedRange<T>
syntax, looks weird.Norbert Kiesel
12/05/2023, 7:58 AMMarcin Wisniowski
12/05/2023, 8:00 AMphldavies
12/05/2023, 8:01 AMMichael de Kaste
12/05/2023, 8:02 AMobject Day5 : Challenge() {
val parsed = input.splitOnEmpty().let {
it.first().substringAfter("seeds: ").split(" ").map { it.toLong() } to it.drop(1).map {
it.lines().drop(1).map { it.split(" ").map { it.toLong() } }
}.map { maps ->
buildMap {
maps.forEach { (target, source, range) ->
put(source..<source + range, target - source)
}
}
}
}
override fun part1(): Any? {
val almanac = parsed.second
val seeds = parsed.first
return seeds.minOf {
almanac.fold(it) { source, range ->
source + (range.entries.firstOrNull { (targetRange, _) -> source in targetRange }?.value ?: 0L)
}
}
}
private fun LongRange.add(add: Long): LongRange = (start + add)..(last + add)
private fun LongRange.rangeIntersect(other: LongRange) =
max(first, other.first)..min(last, other.last)
override fun part2(): Any? {
val almanac = parsed.second
val seeds = parsed.first.chunked(2).map { (seed, range) -> seed..<seed + range }
fun recursiveMinimalSliver(range: LongRange, step: Int): Long {
return when (step) {
almanac.size -> range.first
else -> almanac[step].mapNotNull { (target, step) ->
target.rangeIntersect(range).takeUnless { it.isEmpty() }?.add(step)
}.minOfOrNull {
recursiveMinimalSliver(it, step + 1)
} ?: range.first
}
}
return seeds.minOf { recursiveMinimalSliver(it, 0) }
}
}
Nikita Merinov
12/05/2023, 8:10 AMfun main() {
println(listOf(1..5, 3..8).unionTwo())
println(listOf(1L..5L, 3L..8L).unionTwo())
}
private fun <T : Comparable<T>> Iterable<ClosedRange<T>>.unionTwo(): ClosedRange<T>? {
val (firstRange, secondRange) = this.toList()
return if (secondRange.start <= firstRange.endInclusive) {
firstRange.start..secondRange.endInclusive
} else {
null
}
}
As long as you only need to compare start's and end's of ranges, Comparable
bound should be enough. Please let me know if that helps.Nikita Merinov
12/05/2023, 8:13 AMMichael de Kaste
12/05/2023, 8:16 AMJan Durovec
12/05/2023, 8:16 AMComparable
Michael de Kaste
12/05/2023, 8:16 AMNikita Merinov
12/05/2023, 8:17 AMNorbert Kiesel
12/05/2023, 8:18 AMNikita Merinov
12/05/2023, 8:19 AMNikita Merinov
12/05/2023, 8:21 AMfun main() {
println(listOf(1..5, 6..8).unionTwo(Int::inc))
println(listOf(1L..5L, 3L..8L).unionTwo(Long::inc))
}
private fun <T : Comparable<T>> Iterable<ClosedRange<T>>.unionTwo(inc: (T) -> T): ClosedRange<T>? {
val (firstRange, secondRange) = this.toList()
return if (secondRange.start <= inc(firstRange.endInclusive)) {
firstRange.start..secondRange.endInclusive
} else {
null
}
}
πJan Durovec
12/05/2023, 8:23 AMNeil Banman
12/05/2023, 8:30 AMJacob
12/05/2023, 8:35 AMNikita Merinov
12/05/2023, 8:43 AMunion
, but you get that signature clash, you simply can use @JvmName
annotation. Smth like:
@JvmName("unionIntRange")
fun Iterable<IntRange>.union(): List<IntRange> {
TODO()
}
@JvmName("unionLongRange")
fun Iterable<LongRange>.union(): List<LongRange> {
TODO()
}
phldavies
12/05/2023, 9:08 AMDan Fingal-Surma
12/05/2023, 9:13 AMDan Fingal-Surma
12/05/2023, 9:14 AMphldavies
12/05/2023, 9:16 AMDan Fingal-Surma
12/05/2023, 9:16 AMDan Fingal-Surma
12/05/2023, 9:52 AMNikita Merinov
12/05/2023, 10:21 AMephemient
12/05/2023, 10:29 AMOzioma Ogbe
12/05/2023, 11:22 AMJonathan Kolberg
12/05/2023, 11:27 AMritesh
12/05/2023, 11:41 AMNikita Merinov
12/05/2023, 1:46 PMEl Anthony
12/05/2023, 2:08 PMjonas.app
12/05/2023, 3:27 PMephemient
12/05/2023, 3:32 PMAndre T
12/05/2023, 3:49 PMritesh
12/05/2023, 4:53 PM[79..92, 55..67]
and map for seed to soil -> [(98..99, 50..51), (50..97, 52..99)]
here first pair is source and second is destination
using βοΈ map and seed range, new soil range we get [81..94, 57..69]
and so on for others... can avoid looping thru all seeds.Dan Fingal-Surma
12/05/2023, 5:46 PMNeil Banman
12/05/2023, 7:20 PMCharles Flynn
12/05/2023, 9:21 PMNorbert Kiesel
12/05/2023, 9:50 PMDan Fingal-Surma
12/05/2023, 9:50 PMDan Fingal-Surma
12/05/2023, 9:51 PMDan Fingal-Surma
12/05/2023, 9:52 PMDan Fingal-Surma
12/05/2023, 9:54 PMMarcin Wisniowski
12/05/2023, 9:57 PMSeems that for some inputs, this "if value does not fall into a listed transformer, pass the unchanged value on to the next mapping" can be ignoredIn some inputs the answer value (smallest location) happens to always pass through a valid mapping, so even though other values would be wrong, the answer will be right.
Tolly Kulczycki
12/05/2023, 9:57 PMMarcin Wisniowski
12/05/2023, 9:57 PMDan Fingal-Surma
12/05/2023, 9:59 PMCharles Flynn
12/05/2023, 10:02 PMMarcin Wisniowski
12/05/2023, 10:06 PMMarcin Wisniowski
12/05/2023, 10:06 PMNeil Banman
12/05/2023, 10:24 PMtodd.ginsberg
12/06/2023, 12:30 AMLongRange
for most things and flipped everything backwards for part 2 and it works. It runs in about a second, so not the best implementation, but I think it is Good Enough. π
β’ Blog
β’ CodeNeil Banman
12/06/2023, 12:51 AMtodd.ginsberg
12/06/2023, 12:55 AMephemient
12/06/2023, 12:56 AMNeil Banman
12/06/2023, 12:58 AMNeil Banman
12/06/2023, 12:58 AMtodd.ginsberg
12/06/2023, 1:00 AMDave
12/06/2023, 5:01 PM