Hey everyone! :wave: I'm curious about how folks ...
# advent-of-code
d
Hey everyone! 👋 I'm curious about how folks approach Advent of Code with Kotlin, and I'd love to hear about your experiences and needs. When you're solving AoC problems, what data structures and algorithms do you find yourself reaching for most often? I'm thinking about things like priority queues, graph algorithms, pathfinding helpers, or maybe specialized collection operations. Are there extension methods on standard collections that you wish existed but find yourself implementing from scratch each year? I'm also wondering whether people tend to build up their own personal utility libraries for AoC over time, or if you prefer to solve each problem from first principles. If there were a well-designed Kotlin library specifically aimed at competitive programming and AoC-style problems, would that be something you'd find valuable, or would it feel like it takes away from the challenge? I'd really appreciate any thoughts you have on what would make the AoC experience smoother in Kotlin, what's currently friction-filled, or what you've built for yourself that others might benefit from. Even if it's just "I always end up copy-pasting my Dijkstra implementation" or "I wish there was a better way to handle 2D grids," that's super helpful context! Thanks in advance for any insights you can share! 🙏
z
I'll kick off the feedback here: I start each year from an empty JVM project, only using the standard library in my solutions. I think I once used a JDK PriorityQueue as well. At most I'll add coroutines as a dependency if something really screams for parallelizing work.
thank you color 1
p
I tend to prefer rolling my own helpers/utilities/data-structures/algorithms to solve puzzles as it gives me a chance to appreciate it more. I will occasionally pull out and share a function/abstraction across days/years but otherwise keep solutions fairly self-contained. I'd probably avoid using a library that takes most of that away and leaves puzzles as just "apply some of these tools". That said, I'm not looking to compete, but rather challenge myself.
❤️ 2
e
I've been copying my build and runner setup around, but have very little shared utility code - PriorityQueue aliased on JVM and self-implemented for other multiplatform targets
🙏 1
j
I reimplement prio queue over and over again, as I feel dirty every time I directly call jdk 😀. Also I know it’s not responsibility of any stdlib, but I’d love to see some good kotlin library for algorithms, from gcd through crt to searching and other goodies I sometimes look for in RosettaCode 🙂
👍 1
e
euler's algorithm is easy enough to open code for fast gcd but then I spend too much time trying to remember the details on how to use the extended version to solve diophantine equations like crt 😅
👀 1
I also find some graph algorithms like dijkstra and a* to be straightforward enough to open code every time, but then trip up on simple things like neighbors of lattice points (like we often have to do in aoc) where I make mistakes annoyingly often… might be better with built-in vector types
👀 1
j
Exactly, the algorithms are not rocket science, yet it’s annoying how often one can make a stupidly stupid mistake at 6:00 in the morning, isn’t it 😀
😁 1
c
I spent waaaay too much of my time creating a template that will let me choose the day, the year and the step (part one or two and demo or real input) and handles reading the file, transforming with the type of information I want (list, array of whatever). And over times, I created a lot of extensions functions to reduce the boring parts and concentrate on the algorithm parts.
🤝 1
d
Adding gcd and lcm to the library is a great idea, thank you @Jakub Gwóźdź!
j
I wonder if I'll ever get tired of reimplementing
data class Pos(...)
every one year...
(which reminds me, I finally need to implement
typealias Pos = Long
with companion functions that treats one half of bits as
row
and another as
column
- should be a benchmark killer)
e
you could
Copy code
@JvmInline
value class IntPair private constructor(private val packed: Long) {
    constructor(first: Into, second: Int) : this(first.toLong().shl(32) or second.toLong().and(0xffffffffL))
    val first: Int
        get() = packed.shr(32).toInt()
    val second: Int
        get() = packed.toInt()
}
plus
copy
and
operator component#
if you want
👀 2
d
Yes, I recommend you to use value class as well
j
yeah I know, that's the plan 🙂 , plus all the methods for operating on it and accessing .row and .col, right? .toString() might be tricky tho.
n
I have a couple of for me important / helpful aspects when solving AoC puzzles: 1. I use unit tests as framework, creating a new test file for every day, because that allows to very easily in IntelliJ run / debug my code. 2. I have a couple of helper classes and functions. Some examples are an CharArea class which simplifies walking through and visualizing the often used 2-dimensional char array, but also some "breadth-first" or "depth-first" tree processing, and even simple helpers like
String.ints()
which extracts all Ints from a string (which is often required to parse the puzzle inputs).
e
yeah I always have a unit test for every day, and usually
./gradlew --continuous jvmTest
running in the background to immediately see results as I code
j
I personally prefer
fun main() { ... }
in every day's file, but then I also have this gem in my `Commons.kt`:
Copy code
inline fun go(expected: Any? = null, desc: String = "", op: () -> Any) {
    val result = op()
    println("$desc$result")
    if (expected != null) check(result.toString() == expected.toString()) { "expected $expected" }
}
and my
main()
calls it with expected results (for examples) like:
Copy code
fun main() {
    go(4, "Example 1a:") { part1(example1) }
    go(2024, "Example 1b:") { part1(example2) }
    go(45213383376616) { part1(readAllText("local/day24_input.txt")) }
    go() { part2(readAllText("local/day24_input.txt")) }
...
}
One thing though - for other events than AoC, I tested (and still am using) the Amper instead of Gradle and it's a bad idea, I don't recommend it. While I like Amper a lot, until it starts doing incremental builds, it's simply not feasible for continuous build/run/fix/build/run/fix/build/run way of working.
🥲 1
d
Thanks so much to those who responded to my earlier question about AoC workflows and utilities! Based on the conversations and my own experiences tackling these problems, I've decided to create a Kotlin library specifically designed to help with Advent of Code and competitive programming challenges like LeetCode or Codeforces. The library is already taking shape with some core functionality. Right now it includes a DisjointSetUnion implementation for efficient set operations, various mathematical helper functions, and some convenient extensions for working with frequency maps. I'm actively working on adding a SegmentTree data structure next, which should be really useful for range query problems like RMQ. I'd genuinely love to hear what you think would make this library more valuable for your own problem-solving. Whether it's specific algorithms you keep reimplementing, data structures you wish were more readily available, or just quality-of-life utilities that would save you time during those late-night AoC sessions, all feedback is super welcome. You can share thoughts here or jump into the discussions on the GitHub repository if you prefer. Really appreciate any input you might have, and I'm excited to build something that could be genuinely useful for the Kotlin AoC community! 🙏 Kodvent library: https://github.com/DmitryNekrasov/kodvent
👀 1
🎉 1
👏 2
kodee happy 3
j
looks like a good start 🙂 - but maybe it'd be a good idea to have it as multiplatform library, since it does not seem to rely on JVM/JDK? I'm thinking Pos, Vector, Dir would be nice to have, but honestly, I don't think it would fit everybody (you know, "she was a LRDU girl, he was a NSWE boy"), people often want it done their own way. but lcm/gcd and Union-Find is a good start, I think there's place for Priority Q as well. Also, love the increment/decrement counters. Just today I was writing exactly that for everybody.codes 🙂
❤️ 1
n
I also have Pos in my AoC repos, but even more helpful is my CharArea class that allows to parse, update, and navigate in 2-dimensional Char arrays. Added some issues to illustrate that.
❤️ 1