Eric Haney
12/15/2023, 7:41 PMasSequence()
. In a lot of Advent of Code solutions, I'm seeing people use maps and filters on lists directly which Kotlin allows you to do but in Java we'd be forced to use Streams in all cases.
Is there a reason to not use sequences in most cases? Is there so much overhead to convert to sequences that makes this not worthwhile for lists of a few hundred elements?Sam
12/15/2023, 8:07 PMDaniel Pitts
12/17/2023, 5:48 PM.toList()
runtime complexity: MutableList.add()
has an O(1) amortized complexity, so for large enough sequences, toList()
is relatively similar in performance as if you were using a List instead.Sam
12/17/2023, 6:45 PMDaniel Pitts
12/17/2023, 7:45 PMDaniel Pitts
12/17/2023, 7:46 PMDaniel Pitts
12/17/2023, 7:47 PMKlitos Kyriacou
12/18/2023, 9:13 AMfun <E> List<E>.myDistinct(): List<E> {
val u = mutableListOf<E>()
this.asSequence().filter { it !in u }.forEach { u += it }
return u
}
println(listOf(1, 2, 5, 2, 1, 1, 3, 4).myDistinct()) // [1, 2, 5, 3, 4]
Suppose you thought, "Oh, this list is so small, I might as well do the operations directly on the list instead of turning it into a sequence":
fun <E> List<E>.myDistinct(): List<E> {
val u = mutableListOf<E>()
this.filter { it !in u }.forEach { u += it }
return u
}
println(listOf(1, 2, 5, 2, 1, 1, 3, 4).myDistinct()) // nothing is filtered out!
The second snippet does not work because the mutable list u
is always empty while the filter
operation is performed on every element.Sam
12/18/2023, 9:15 AMDaniel Pitts
12/18/2023, 3:57 PMWout Werkman
12/18/2023, 5:02 PMfun day9a(input: String): Int {
return input
.lines()
.map { it.split(" ").map { it.toInt() } }
.map { history ->
generateSequence(history) { it.zipWithNext { l, r -> r - l } }
.takeWhile { !it.all { it == 0 } }
.sumOf { it.last() }
}.sum()
}
Day 8:
fun String.infinitelyRepeating(): Sequence<Char> = generateSequence { asSequence() }.flatten()
fun Node.numberOfStepsUntilReachingFirstEndNode(): Int =
directionSequence
.infinitelyRepeating()
.runningFold(this) { current, direction -> current.findNextNodeGoingTowards(direction) }
.indexOfFirst { it.isEndNode() }
If you ever think you needed sequences for their performance in AoC, please let me know 🙂