<Advent of Code 2023 day 15> :thread:
# advent-of-code
a
kodee happy 1
m
Quite a simple one today.
💯 3
b
yea, that one was one of the easiest yet
makes me nervious, they're softening us up for something this weekend
m
And I think I found an IDE / inference bug.
IDE says
map/sum
can be simplified into
sumOf
But it can't
👍 1
m
'as Int' needs to be at the end of your line
My solution for today, lots of text in the challenge description, took me several parses to understand part 2. However, rare for me, I got both answers correct on first attempt this time, haha.
b
yea i def spent more time reading the puzzle than solving it
m
'as Int' needs to be at the end of your line
Yeah that's fine, the point is that the IDE suggests a quick fix that breaks code that was compiling before
Part 1
Part 2
m
made the assumption that all that 'hashmap' explanation, is already how 'linkedhashmap's work underwater.
If the operation character is a dash (-), go to the relevant box and remove the lens with the given label if it is present in the box. Then, move any remaining lenses as far forward in the box as they can go without changing their order, filling any space made by removing the indicated lens. (If no lens in that box has the given label, nothing happens.)
and
If there is not already a lens in the box with the same label, add the lens to the box immediately behind any lenses already in the box. Don't move any of the other lenses when you do this. If there aren't any lenses in the box, the new lens goes all the way to the front of the box.
luckily it did 😁
j
strange. 15 days without dijkstra or a*
b
for part 2 i used a list of maps lf labels to fl, adding and removing from the maps preserves order exactly like they describe without any work
image.png
n
Any reason to prefer
Array(256) { mutableListOf<Lens>() }
or
MutableList(256) { mutableListOf<Lens>() }
?
j
I used Array, but frankly List would do as well, doesn’t need to be MutableList
n
Yeah,
List
. I used
Array
as well, but see most others here do not.
a
Do they write such confusing descriptions on purpose? ) to side track LLMs? ) Anyway, it's straightforward today - I was worried that my code with all immutable data structures would be slow but it was instantaneous. https://github.com/andriyo/advent-of-code-kotlin-2023/blob/main/src/Day15.kt implicit LinkedHashMap of course helped a lot
n
Looking at the AoC picture, looks like we will be back on the Snow Island on Day 25.
definitely advent of reading comprehension today
👍 2
m
image.png,image.png
😂 4
e
@Marcin Wisniowski @Michael de Kaste https://youtrack.jetbrains.com/issue/KT-46360 I would definitely prefer to write
0.toInt()
instead of
as Int
though, it's safer if anything changes
👍 1
p
A nice quick one today - makes for a pleasant Friday morning.
I definitely struggled with reading comprehension - I spent far too long still hashing the whole string rather than just the label...
p
e
it did take a bit more thought for me in Haskell and Rust, where
LinkedHashMap
doesn't exist
but yeah, perhaps we just shouldn't expect any particular difficulty distribution
p
But it’s actually nice! I remember people giving up at some point in the last years because things just got harder and harder. Maybe some easy puzzles keep everyone more motivated in the long run
e
what if day 25 part 1 requires finding a counterexample to the collatz conjecture
k
I used a set to track of insertion order and a map to track the focal value.
m
I'm tempted to use todays implementation for any <String, Int> map in the remaining days 😃
w
The only pattern I see right now is:
Copy code
val difficult = day in setOf(5, 10, 12)
Still figuring out the mathematical formula for that…
🎲 1
Difficult can be classified as the top 100 spot on the global leaderboard taking more than 20 minutes
e
day 9 taught you how to make such a mathematical formula, right? 😛
p
Copy code
5  10  12   [11]?
  5   2   [-1]?
    -3  [-3?]
I'm not sure we can go backwards...
w
Another metric can be that if you try to explain your solution for the day to your colleagues they stare vaguely into the distance with hollow eyes…
p
That happens far too frequently for me...
w
So day 14.5 was really difficult I see!
p
https://www.maurits.vdschee.nl/scatterplot/ from the scatter plots there seems to be two series of difficulties - the next medium difficulty looks to be d18, the next hard difficulty will be d20
m
@ephemient I think you meant to ping me, not the other Marcin of Effective Kotlin fame? 😄
e
ah I did. hope I fixed it…
w
By the way I am using a DefaultMap implementation for a lot of challenges like today, basically a map which automatically puts a configurable default value in case it does not exist:
Copy code
val map = data.fold(
        defaultMutableMapOf<Long, MutableMap<String, Long>>(
            putValueImplicitly = true,
            defaultValue = { linkedMapOf() })
    ) { map, item ->
        val (label, rest) = item.split('-', '=')
        val boxNumber = hash(label)
        if (item.contains('=')) {
            val focalLength = rest.toLong()
            map[boxNumber][label] = focalLength
        } else {
            map[boxNumber].remove(label)
        }
        map
    }
This allows you to use a more natural syntax and get rid of all the null checks, getOrPut etc.
e
ah, I just pre-allocated them all,
List(256) { mutableMapOf() }
and indexing a list is non-null
t
That was a nice easy one (which I appreciate, since I have the day off and can now go do other things). Thankfully,
mutableMapOf()
provides a
LinkedHashMap
which retains insertion order, making part 2 pretty straight forward (yay,
compute
which I never get to use!). • BlogCode
e
fyi
compute
is a
java.util.Map
interface default method; Kotlin's version is
getOrPut
. on JVM there isn't a whole ton of difference aside from that Kotlin doesn't enforce null-safety on the former; on non-JVM you can only use the latter
t
OH, nice, I had no idea. I'll remember that for the future - thanks! 🙂
c
In this case you can just do a simple assignment.
Copy code
boxes[label.hash()][label] = instruction.substringAfter("=").toInt()
Suspiciously straightforward today but i'm not feeling well so I'll take it 🙂
t
Man you’re right. 🤦‍♂️ Sometimes I get attached to an idea and stick with it when I shouldn’t. I hope you feel better soon
@Charles Flynn thanks for the tip. Edited my blog post and credited you with the fix.
🙂 1
n
Thankfully,
mutableMapOf()
provides a
LinkedHashMap
which retains insertion order, making part 2 pretty straight forward
Also pertaining to some implementations of Day 14. As a hobbyist, nothing I do is ever in production. But again, in the bizarre scenario where you needed to solve AoC puzzles in a production environment, would it be kosher to rely on the
Map
or
Set
interface and associated factory methods, given that the interface does not guarantee retention of insertion order? Realistically, Kotlin is never going to change its factory methods to an unordered HashMap as it would break a ton of stuff.
j
I would make it explicit mostly to express the intent. If retention of insertion order is an important property of the algorithm, then the code should reflect that. I agree that Kotlin would never change it, and even if they (or some future colleague) did, surely your tests would catch it anyway, right?
👍 1
a
@Neil Banman I had the same sentiment towards implicit behavior - it should be part of the API contract and it is if you manage to use LinkedHashMap explicitly. Only by seeing that it's an object of type LinkedHashMap you know its full behavior (and even that is not guaranteed as LinkedHashMap is not final). It would be great to have a set of marker interfaces describing internal behavior of a class when it affects how client could or should use it. I haven't seen anything like that in any language , to be honest. I think I could have used linkedMapOf() and LinkedHashMap in my code directly and that would be better, but there just not enough framework level functions for LinkedHashMap. I mostly use plus() and minus() in my immutable code but those are not defined for LinkedHashMap so I either do casting (ugly!) or write my own extension functions (reimplementing framework - ugly and sometimes impossible).
👍 1
a
mutableMap() handles all