winny
2020-12-11 13:22:28

Thanks for pointing this out. TIL there are quite a few of these file shortcuts!


ben.knoble
2020-12-11 20:39:27

Enjoyed the game-of-life; added animations to mine for fun, but had to shrink my terminals font size way down to actually watch them on my full input :slightly_smiling_face:


badkins
2020-12-11 20:45:35

I missed a key insight again :)


badkins
2020-12-11 20:47:31

After I wrote my solutions. I took a look at this <https://github.com/tckmn/polyaoc–2020/blob/master/11/rb/11.rb|Ruby version> (this person has been doing great work), and realized you can compute the first seats ahead of time, so I <https://github.com/lojic/LearningRacket/blob/master/advent-of-code–2020/day11-rb.rkt|ported it to Racket> , and naturally, it was considerably faster. I didn’t take any time to Racketize it, just did a port as close to the Ruby as I could in a hurry.


badkins
2020-12-11 20:50:42

In my versions, I didn’t want to allocate much, so I just used two vectors (previous & current). My hunch is that if I did that in the port above, I’d gain some speed, compared to allocating a new vector of vectors each time.


ben.knoble
2020-12-11 20:53:24

I think I’m having trouble following; what is sight ? If it’s just the visible seats in the first generation, the ruby code never updates it, so that seems odd—makes me thing it has to be the possibly visible seats (like list of points to check or something)

I actually recalculate the visible seats each time; red-black trees and tail-recursion were “fast enough” (though not blindingly fast)


badkins
2020-12-11 20:55:07

For any given seat, the first visible seat in all 8 directions never changes.


ben.knoble
2020-12-11 20:55:24

ah. I missed that. oh well :slightly_smiling_face:


badkins
2020-12-11 20:55:39

Yeah, it took me a while to see what they were doing!


badkins
2020-12-11 20:56:20

I just checked, and there are only 90 iterations until it stabilizes, so allocating 90 new vectors is no big deal for Racket; hence, I’m not going to bother experimenting with not allocating :)


badkins
2020-12-11 20:57:31

I got about a 7x speedup using the precomputed sight table.


ben.knoble
2020-12-11 20:57:58

That makes sense; I’m tempted to try it on my sml solution and see what happens


badkins
2020-12-11 20:59:59

It’s humbling when <https://adventofcode.com/2020/leaderboard/day/11|people are producing> concise, elegant & efficient solutions in about 5 minutes !!


samth
2020-12-11 21:02:09

you could make it faster by using a 1D vector instead of a 2D one


badkins
2020-12-11 21:05:31

@samth yes, my original solution was pretty efficient except for lacking the key insight of precomputing the first seat :) I used two 1D vectors and vector-copy! to reset each iteration.


badkins
2020-12-11 21:06:10

I may modify my original to use the precomputed table (instead of porting the Ruby), and see what the speedup is.


badkins
2020-12-11 21:06:58

I keep learning little tidbits about Racket though, so it’s been profitable in addition to humbling :)



badkins
2020-12-11 21:08:08

I continue to find let loop to be noticeably faster than the for family.


badkins
2020-12-11 21:26:49

Wow, using macros instead of functions for the following got me a 7x speedup ! (define-syntax-rule (is-empty? seat) (char=? empty-loc seat)) (define-syntax-rule (is-floor? seat) (char=? floor-loc seat)) (define-syntax-rule (is-occupied? seat) (char=? occupied-loc seat))


samth
2020-12-11 21:27:41

That is surprising


badkins
2020-12-11 21:28:02

I agree, so I changed them back, measured again to confirm the results.


badkins
2020-12-11 21:28:24

1,157ms w/ functions & 172ms w/ macros.


badkins
2020-12-11 21:29:28

I’m on Racket BC 7.5


badkins
2020-12-11 21:31:51

Oh wow, @samth it wasn’t function vs. macro!


badkins
2020-12-11 21:32:58

Instead of: (define (is-empty? seat) (char=? empty-loc seat)) I was using: (define is-empty? (curry char=? empty-loc)) because point-free seemed cool - why the heck does that impose a performance penalty?


badkins
2020-12-11 21:33:30

7x is a pretty stiff penalty


samth
2020-12-11 21:34:12

curry is creating a function that does runtime dispatch


ben.knoble
2020-12-11 21:34:35

In SML it sure doesn’t :slightly_smiling_face: if curry/compose/etc. are slower in racket, it would turn me off of that style of writing (which I happen to enjoy).


popa.bogdanp
2020-12-11 21:57:21

Looks like precomputing the seats doesn’t make much of a difference on the inputs that the site generates:

~/s/aoc2020 (master)&gt; racket day11.rkt cpu time: 70 real time: 72 gc time: 4 2406 cpu time: 69 real time: 71 gc time: 1 2149 ~/s/aoc2020 (master)&gt; racket day11-rb.rkt cpu time: 116 real time: 118 gc time: 36 2406 cpu time: 101 real time: 103 gc time: 0 2149 Though pre-computing would probably be faster if the inputs were larger and more sparse.

day11.rkt is https://github.com/Bogdanp/aoc2020/blob/e3ff6e1718b7d08fc585b33aa50477f4cb32c3e6/day11.rkt\|here and day11-rb.rkt is the one from your repo.


samth
2020-12-11 22:02:28

@popa.bogdanp did you try with a 1d vector and doing multiplication in ref?


badkins
2020-12-11 22:04:21

I’m getting 170ms now with my original (non-precomputed) on a Macbook Pro 16", and about 175ms with day11-rb.rktnow that I got rid of curry !!


badkins
2020-12-11 22:07:08

I’ll report back with the precomputed version, but I expect it typically only has to check 2 or 3 positions before finding a seat, so maybe not a big help.


popa.bogdanp
2020-12-11 22:21:06

@samth looks like no difference:

~/s/aoc2020 (master)&gt; racket day11.rkt cpu time: 73 real time: 74 gc time: 3 2406 cpu time: 69 real time: 71 gc time: 1 2149 ~/s/aoc2020 (master)&gt; racket day11-wide.rkt cpu time: 65 real time: 67 gc time: 3 2406 cpu time: 74 real time: 76 gc time: 5 2149


samth
2020-12-11 22:22:22

Well, 10% isn’t no difference :)


popa.bogdanp
2020-12-11 22:27:34

Fair, but I think that difference might just be noise (I’m on battery power). Here’s what it looks like when I bump the iteration count to 20:

~/s/aoc2020 (master)&gt; racket day11.rkt cpu time: 1310 real time: 1339 gc time: 0 cpu time: 1438 real time: 1473 gc time: 11 ~/s/aoc2020 (master)&gt; racket day11-wide.rkt cpu time: 1273 real time: 1301 gc time: 0 cpu time: 1434 real time: 1469 gc time: 10


samth
2020-12-11 22:29:40

So maybe real but not 10%


badkins
2020-12-12 00:56:57

Had a power outage here, but I finally got some results. <https://github.com/lojic/LearningRacket/blob/master/advent-of-code–2020/day11–2.rkt|Old Part 2> which requires <https://github.com/lojic/LearningRacket/blob/master/advent-of-code–2020/day11–1.rkt|Part 1> is about 222 ms. The <https://github.com/lojic/LearningRacket/blob/master/advent-of-code–2020/day11–2b.rkt|New Part 2> w/ precomputed seats is about 112 ms.


badkins
2020-12-12 01:25:54

Installed Racket CS 7.9 out of curiosity. Timings are similar.


badkins
2020-12-12 01:26:08

But at least I’m on a cool, recent version now!


badkins
2020-12-12 01:38:55

@mbutterick I like your use of complex numbers for Day 11 - nice job!


me1890
2020-12-12 06:44:22

Complex numbers made today really easy too