ben.knoble
2020-12-23 17:36:20

Huh, went from ~4.5s to ~1.2s just by swapping the fifos for lists. Must be that the list library is better optimized, either at the language or lower level.


ben.knoble
2020-12-23 17:37:17

I’m looking at the problem; did you or anyone come up with a clever way to treat the whole list as a single number instead of as a list of numbers? I imagine that would be really fast if the operations aren’t too bad.


jonathanhwchan
2020-12-23 18:25:37

https://github.com/ionathanch/adventofcode-2020/blob/main/src/23.rkt\|https://github.com/ionathanch/adventofcode-2020/blob/main/src/23.rkt This one was a doozy I started doing part 2 in C bc I didn’t know how else to manipulate pointers lol But it was really slow trying to find the cup with a given label and I found myself wishing I had a map but guess what. Racket has hash And finally I went from hash to vector since it’s ints to ints


ben.knoble
2020-12-23 19:53:32

Just found out that my list-solution for part1 would take maybe ~2300+ days to run, gonna have to do something different :slightly_smiling_face:


badkins
2020-12-23 20:53:55

I wrote a simple circular queue for Part 1, and I really just wanted to use it as-is for Part 2, but I think it would take 11 hours :) I’m guessing there’s a clever, non-brute force approach, since AoC mentions there are solutions that run in less than 15 seconds on 10 year old hardware.


badkins
2020-12-23 20:54:34

I did a bit of tuning, and got it to 235 moves/second, but that’s not even close to being fast enough.


jonathanhwchan
2020-12-23 20:57:59

I tried to figure out the pattern manually and derived smth for up to ~250000 moves but the pattern started breaking bc it was looping back from 1000000 to the start so I gave up :man-shrugging: It looked a lot like a Project Euler problem and I was hoping there’d be some sort of closed-ish form you could compute


badkins
2020-12-23 20:58:13

Hmm… from the comments above, it seems a brute force approach is doable w/ some more tuning. I didn’t get around to using a hash for the lookup, that might get me there.


badkins
2020-12-23 21:27:36

Wow! Replaced my function to lookup the cup in the circular queue by label with (vector-ref vec label), and it dropped from 11 hours to 2.2 seconds :)


badkins
2020-12-23 21:28:32

I knew a hash or vector reference would be much quicker on that, but I didn’t realize what percentage of the run time was taken up by that operation - apparently quite a bit! I usually have better intuition than that :)


ben.knoble
2020-12-23 21:42:01

@jonathanhwchan trying to decipher your solution; does your vector map cup -> next cup? If so, that’s kind of genius


jonathanhwchan
2020-12-23 21:55:43

Yeah What you don’t see is the half dozen other implementations to get to that conclusion lol


badkins
2020-12-23 22:01:32

Interesting. I didn’t know that’s what you were doing, but as soon as I read vector instead of hash above, I created a cross reference vector to map label to queue node. I still can’t believe the 21,000x speedup ! Here’s <https://github.com/lojic/LearningRacket/blob/master/advent-of-code–2020/day23.rkt|the resulting code>


badkins
2020-12-23 22:01:55

So glad I was able to reuse the circular queue from part 1 :)


badkins
2020-12-23 22:04:07

@jonathanhwchan if I’m understanding correctly that you bypassed a queue entirely and, in effect, implemented the queue and cross reference in the vector, that must be pretty fast.


badkins
2020-12-23 22:05:07

Although setting a few next prev pointers probably doesn’t add much overhead. My GC time was only 185 ms.


jonathanhwchan
2020-12-23 22:07:06

Yeah, setting values in the vector probably isn’t all that much faster than moving a few pointers around


badkins
2020-12-23 22:08:09

I was getting tired of writing throw away code, so I figured I’d at least get a rudimentary circular queue out of today. Once I add some robustness, it might be useable later :)


ben.knoble
2020-12-23 23:23:36

Sigh. I tried immutable vectors, and performance was unacceptable. With mutable arrays, I get about 100k moves per 2–3 seconds, so 10 million takes 3–5 minutes if my math is right. I’m a little jealous of racket rn


badkins
2020-12-24 00:02:59

I thought @jonathanhwchan’s solution was ideal for Julia, so <https://github.com/lojic/LearningRacket/blob/master/advent-of-code–2020/day23–2.jl|I ported it to Julia> , and it runs 12x faster than my Racket solution. It takes 0.18 seconds for Part 2.


badkins
2020-12-24 00:03:20

@ben.knoble you using SML?


badkins
2020-12-24 00:05:17

I’ve pretty much been coding only in Racket for the last couple years, and it fits me very well. However, occasionally, it does feel good to just have some loops and assignment statements :)


badkins
2020-12-24 00:05:41

Especially when it’s amazingly fast.


ben.knoble
2020-12-24 00:09:45

@badkins yeah; here’s the link. See the history for lists; i didnt commit the vector version but it’s almost the same https://github.com/benknoble/advent2020/blob/main/day23/solution.sml\|https://github.com/benknoble/advent2020/blob/main/day23/solution.sml


badkins
2020-12-24 00:24:14

What compiler are you using? I wonder if MLton would be faster.


badkins
2020-12-24 01:41:43

I did a <https://github.com/lojic/LearningRacket/blob/master/advent-of-code–2020/day23-vector.rkt|Racket port of my Julia port> of Jonathan’s code. I’m getting 0.28 seconds (vs. 2.2 seconds w/ my queue solution), so Racket is pretty speedy. Only 1.6x Julia is pretty darn fast.


jonathanhwchan
2020-12-24 01:45:57

I tried porting that solution to C but I think I’m having problems with not being able to malloc all of the memory at once lol


badkins
2020-12-24 01:50:32

Using <https://github.com/lojic/LearningRacket/blob/master/advent-of-code–2020/day23-vector-unsafe.rkt|all the unsafe-fx bells and whistles> got down to 0.24 seconds. I don’t think the ugliness & unsafety is worth the 17% speedup.


badkins
2020-12-24 01:52:30

@jonathanhwchan I did a C version for Day 15, and it was a pain to get it working (mainly due to not having coded C in a long time), the Julia version on Day 15 was both faster than the C version, and much, much nicer to program! :) I think I’d only use C when forced to i.e. for a microcontroller, or similar need.


badkins
2020-12-24 01:54:00

@jonathanhwchan you should be able to allocate the vector on the stack in C. I did that for <https://github.com/lojic/LearningRacket/blob/master/advent-of-code–2020/day15.c|my Day15 C version> by using a command line of: gcc -O3 -Wl,-stack_size -Wl,32000000 day15.c to get enough stack space.


badkins
2020-12-24 01:54:41

I’m not motivated to try because I think the Julia version would win :)


badkins
2020-12-24 01:55:24

… and one based arrays are pretty handy for this.


haskal
2020-12-24 06:36:24

day 24 spoilers,


haskal
2020-12-24 06:40:15

https://git.lain.faith/haskal/aoc2020/src/branch/aoc2020/24.rkt

i ended up using complex numbers representing truncated cubical coordinates as keys to a hash of #t (black) or #f (white). part 2 is ~4.7 seconds notably, using complex numbers pretty significantly speeds up execution vs a position struct


me1890
2020-12-24 06:50:10

I used complex numbers too, but just used a slightly different mapping that looks closer to regular hexagons



jonathanhwchan
2020-12-24 07:21:02

haskal’s coords look like axial coords from here https://www.redblobgames.com/grids/hexagons/


haskal
2020-12-24 07:26:33

yeah it’s cubical coords except truncate one of them because you only need 2


haskal
2020-12-24 07:26:39

looks like that page explains the scheme


me1890
2020-12-24 07:28:40

I think i used the same coordinates but just rotated a bit


haskal
2020-12-24 07:31:22

yeah mine are a bit obtuse and perhaps rotated 60 degrees away from what you’d expect from the cardinal directions but ignore that lol


me1890
2020-12-24 07:34:06

You probably avoided one slight issue i had. At first i was using 0.5+i for my offsets and i was getting some rounding errors, so i just had to switch to rationals