massung
2021-12-15 15:51:47

I ended up just coding up an a* library in common lisp that is generic (handles arbitrary graphs) and then just imported it.

I’m sure python likely just has pip install astar :slightly_smiling_face:


massung
2021-12-15 15:54:52

@badkins - pinging you here since I think your post (re: graph module) in #general was intended to be here?


badkins
2021-12-15 15:56:50

No, it was a general question, and I haven’t implemented part 2 yet, so I didn’t want to see any spoilers. Although, if the graph module can’t handle the new size, I’ll have to think of something else :)


badkins
2021-12-15 15:57:54

It was fast enough for 100x100, but I’m not 100% sure it will be for 500x500 since it’s computing all shortest paths from the source i.e. 250K of them :)


massung
2021-12-15 15:59:20

I hand coded A*, but also decided that while I was doing it I might as well package it up nicely for generic use in the future. It ends up taking ~7s to run on the large data set. Coming up with a better H(x,y) function other than a simple sum-of-distances would likely produce faster results.


massung
2021-12-15 16:00:22

The only thing about part 2 that’s “tricky” other than the size is how the tiling is done (and wrapping of numbers). That tripped me up a bit.


popa.bogdanp
2021-12-15 16:30:18

I got my part 2 down from 5s to about 300ms by changing the sorting function in my heap. Rather than storing pairs of (position, cost) and having the function extract the cost from the pair, I used < and packed the cost and position into a fixnum, with the cost shifted 32 bits to the left.


ben.knoble
2021-12-15 16:42:20

<https://github.com/benknoble/advent2021/blob/main/day15/solution.rkt> Building the graph for part2 took me a while to get right. I… did not write an A*, and just use graph’s dijkstra :slightly_smiling_face: 240s, of which 75s is building the graph, for part2 (998000 edges is a lot).


badkins
2021-12-15 18:55:02

<https://github.com/lojic/LearningRacket/blob/master/advent-of-code–2021/solutions/day15/day15.rkt|Day 15> - rather slow for part 2 using dijkstra from graph, but it got it done :)


massung
2021-12-15 19:35:14

Okay… I’ve finished spending way too much time on this one. But, I’ve come to the conclusion that it’s a bad puzzle (IMO). All that’s being measured is whether or not you can actually code Dijkstra (or know to use a library) and the performance of your language.

Basically it’s a pathological setup that can’t be optimized:

• There are no obstacles/impassable nodes • There are no diagonal moves allows (meaning any heuristic needs to be Manhattan) • The start and goal nodes are at corners Basically at every step you are guaranteeing that you’ll improve your position exactly the same amount (heuristically) regardless of which choice is made. The only difference is in the cost per node.

So, regardless of path chosen, eventually you’ll run into a situation where your priority queue of nodes to search will be to go back near the beginning and try the other way. Except that most of the time, you aren’t improving anything.

If you attempt to modify the heuristic to value being closer to the goal more (a wise thing to do), you end up overestimating the value of the path you’re searching and never backtrack to find the optimal path.

For my part 2, if I run it with no heuristic (read: dijkstra) or manhattan, I end up with essentially the same results and the correct optimal cost:

#&lt;ASTAR::PATH of length 998 with cost 2846&gt; 249996 The second value is the total number of nodes searched (so 99.99%). And it takes 1.4s to do.

If I instead use a better heuristic overvaluing being closer to the end goal, the search space is reduced considerably (0.04s), but I don’t get the optimal path:

#&lt;ASTAR::PATH of length 998 with cost 3100&gt; 7734 So, anyway, unlike most every other “large problem space” puzzle AOC has done in the past, this one was unoptimizable. :disappointed:


massung
2021-12-15 19:36:48

If anyone happens to know of a heuristic function they’d like me to try out, though, I’m more than happy to.


jgeddes
2021-12-15 20:36:40

~36~ (Edit: sorry, cat on the keyboard …)


ben.knoble
2021-12-15 21:32:11

I would have used a bunch more emoticons in that reaction, but Slack doesnt have all the meow- emoji that Discord does :)


badkins
2021-12-16 02:55:32

I coded up a <https://github.com/lojic/LearningRacket/blob/master/advent-of-code–2021/solutions/day15/day15-conspicio.rkt|concise & fast version> using ideas I gleaned from a few different solutions. Takes about 375 ms for part 2.


badkins
2021-12-16 03:20:53

A 2,000 x 2,000 grid takes less than 6 seconds.


popa.bogdanp
2021-12-16 06:26:43

Day 16 spoilers


popa.bogdanp
2021-12-16 06:26:51

Padding tripped me up so much today lol


massung
2021-12-16 06:30:11

@badkins - using the code code you posted and having it load my real data, part 2 takes 5 seconds to run. Are you sure? The code looks exactly the same as dijkstra: add distance from start + cost of next space onto sorted list, pop next best, repeat until goal.

I also added a nodes-searched counter that’s incremented each iteration of the loop and it searched 249,998 nodes (on my data), which is 99.999% of the grid.



massung
2021-12-16 06:31:42

This was one day I was really happy for Common Lisp. Using ldb made this one an absolute breeze to do.



popa.bogdanp
2021-12-16 06:33:25

That’s neat. I decided to treat it as a string parsing problem early on and that probably made it harder for me than necessary.


massung
2021-12-16 06:36:49

One thing that has struck me doing AOC the past few years is that whatever first idea comes to my mind when I dive in either makes or breaks me.

I’ve also discovered that my threshold for giving up on an idea and starting fresh is probably higher than it should be. It makes me wonder if that threshold is the same - or lower (or maybe even higher?) - at work when discussing solutions w/ teammates. I’d like to think it’s lower and I can be convinced to give up/listen to other ideas.

I think I’ll ask about that w/ some blunt co-workers tomorrow. :wink:


massung
2021-12-16 06:37:57

Day 8 this year was definitely like that for me. I think it was 3am before I finally decided it was time to stop, go to sleep, etc. Woke up, took a different approach, and was done in 20 minutes.


popa.bogdanp
2021-12-16 06:42:51

I know what you mean. Compared to work, though, I think the competitive factor plays a big role here in how much I dig into my first approach, because it’s a sunk cost. Even though I know it’s pointless for me to try and get a high score (these get posted at 7am my time, which is about when I get up), I still pressure myself to do them quickly.


massung
2021-12-16 06:43:26

@popa.bogdanp Just looking at your code… Could your data just be defined as (format "~b" (string-&gt;number (read-line) 16)) ?


massung
2021-12-16 06:43:41

instead of all the manual conversion from hex -> binary?


popa.bogdanp
2021-12-16 06:44:27

I tried that initially and something was wrong with the result so I just changed it without investigating


popa.bogdanp
2021-12-16 06:44:38

I’ll probably clean it up later today :D


massung
2021-12-16 06:44:51

everything else is neat to look at. love seeing different solutions


massung
2021-12-16 06:46:46

> something was wrong with the result My guess is that - since you were dealing with strings (as opposed to actual bits/numbers) - you would have been missing leading 0’s in the MSB positions. Your string conversion handles that.


popa.bogdanp
2021-12-16 06:59:18

That must’ve been it.