This season of AoC has taught me, among other thin...
# advent-of-code
m
This season of AoC has taught me, among other things, the great value of live templates. For example, I have one for Dijkstra. Saved me a lot of time, and is much better than something in a library, because the code always needs to be customized. I will create one for the typical Pos/neighbors data class as well. Other things, like transpose, should be in the standard library, but until they are we can simply put them in a util package and use them when needed.
p
Can you share your util package and what you think should be in stdlib?
m
Oh, my util package is really small and only covers some basics. It’s also out of date - I have GSON in there for parsing JSON, when this season I learned that the builtin Kotlin stuff is as easy to use. https://github.com/MikeEnRegalia/advent-of-code/tree/master/src/main/kotlin/util
I think that @ephemient has a really good handle on what should/could be added to the stdlib. I work almost exclusively with Kotlin/JVM, so my point of view is somewhat incomplete. I have some ideas about what would help me a lot in the stdlib when doing puzzles, but as @elizarov keeps reminding me, usefulness in coding challenges is not sufficient reason for having things in a stdlib. I think that a transpose would make sense, maybe also more things that we know from Python’s itertools, like permutations and combinations. However, this season I didn’t miss those. Like I said above, for most things that come up a lot IMHO live templates are more useful.
And I did suggest the chunkedBy method, although I would name it split:
List<T>.split(sep: T): List<List<T>>
and/or
List<T>.split(sep: (T) -> Boolean): List<List<T>>
Then I could do
lines.split("")
or
lines.split { it.isBlank() }
.
e
in the meanwhile, there is a hack:
Copy code
inline fun <T> Iterable<T>.splitOnce(predicate: (T) -> Boolean): Pair<List<T>, List<T>> {
    val iterator = iterator()
    return Iterable { iterator }.takeWhile { !predicate(it) } to Iterable { iterator }.toList()
}
although I don't think the collections extensions are guaranteed to consume the iterator just once... no good reason for them to behave otherwise though
l
just for my understanding of what you've written there @ephemient, is that
splitOnce
something you can then use in a declaration like the following?
Copy code
val foo = listOf(1,2,3,4)
sis that
just for my understanding of what you've written there @ephemient, is that
splitOnce
something you can then use in a declaration such as the following?
Copy code
val foo = listOf(1,2,3,4,5)
val (firstTwo, rest) = foo.splitOnce { it.sign = 0 }  
// firstTwo == listOf(1,2)
// rest = listOf(3,4,5)
Or how would you use it?
e
no, more like
Copy code
val (a, b) = listOf(1, 2, 3, 4, 5).splitOnce { it % 2 == 0 }
a == listOf(1)
b == listOf(3, 4, 5)
there were a couple problems where
.splitOnce(String::isEmpty)
would have been useful
if you wanted the delimiter you'd need a slightly different implementation
l
ah it drops the first match, more like
String.split
(which now is clear from the name) than a version of
takeWhile
that destructures to the matches and the remainder. thanks for the help!
e
yes, the function you mention is called
span
in Haskell and is effectively equivalent to `takeWhile`+`dropWhile`. there's no one-line alternative in Kotlin but I think it could may useful as well
e
I've added
split
to my own AoC utils (called it
parts
) after seeing it for a second time, but I cannot find enough motivation to even ask for adding it to the standard library. Why would you ever need it in any kind of business context?