badkins
2021-12-6 16:32:37

I was pleased with <https://github.com/lojic/LearningRacket/blob/master/advent-of-code–2021/solutions/day06/day06.rkt|my Day 6> - I did try and make it concise, but I don’t think I “golfed” it. I suppose that’s in the eye of the beholder though. I really tried to find a math solution, but either I don’t have the chops, or there isn’t a clean one.


badkins
2021-12-6 16:34:09

@massung it looks like you may have posted Bogdan’s repo my mistake above.



badkins
2021-12-6 16:47:33

Nice! Curious why the line break after gamma, but not epsilon in solve-part1 ?


ben.knoble
2021-12-6 16:55:11

No idea :) this is @sorawee ‘s formatter


sorawee
2021-12-6 16:58:04

I suppose that @ben.knoble ran this in Discord. I configured raco fmt in Discord to have width limit of 75 characters, so that it fits the message area of Discord. This width limit is why it breaks on gamma but not epsilon.


sorawee
2021-12-6 17:00:45

More formally, the code formatter will attempt to format code in a way that minimize the number of lines, subjected to the constraint that the code fits the page width limit. That means it prefers

(let ([xxx yyy]) zzz) since it has fewer lines, but if both being in the same line causes the line to overflow, it would need to switch to:

(let ([xxx yyy]) zzz) instead.


ben.knoble
2021-12-6 17:02:58

I thought I had a nice mathy solution, but it wasnt fast enough. Then I saw a matrix-exponent + matrix-vector solution, and I’m working on porting it; fingers crossed it runs quickly. Part1 i have in 5ms, but part 2 was just too slow


kristian.lundstrom
2021-12-6 17:04:01

@kristian.lundstrom has joined the channel


massung
2021-12-6 17:04:31

A friend showed me his solution and I feel sooo stupid right now. Mine’s plenty fast (~4ms) for part 2, but his shows why the puzzle drops at midnight aren’t ideal :slightly_smiling_face:


massung
2021-12-6 17:04:51

Recoding mine now to see the difference


massung
2021-12-6 17:14:23

Yep. Simpler and runs in 1ms now instead of 4


massung
2021-12-6 17:15:15

How I felt…


popa.bogdanp
2021-12-6 17:18:11

I’ve also thought about switching the hash for a vector, but the hash version already takes less than 1ms on my machine so I didn’t bother :smile:


badkins
2021-12-6 17:24:28

I ended up golfing my main version a little too much, so for penance, here’s <https://github.com/lojic/LearningRacket/blob/master/advent-of-code–2021/solutions/day06/day06-annotated.rkt|an annotated version> that’s much more readable. Poor Ben is sometimes getting my commentary twice since he’s in our local slack also :)


massung
2021-12-6 17:32:16

Funny how your mind goes to a solution right away and how it influences things. I went straight to “there’s gotta be an equation for this” and just couldn’t shake it.


ben.knoble
2021-12-6 17:41:45

Loo no worries Badkins :) still upset my clever version is too slow for part 2


ben.knoble
2021-12-6 17:45:45

Actually, it barfed: map: contract violation expected: list? given: '((23 (155 148 141 134 127 120 113 106 99 92 85 78 71 64 57 50 43 36 29 22 15 8 1)) (22 (148 141 134 127 120 113 106 99 92 85 78 71 64 57 50 43 36 29 22 15 8 1)) (21 (141 134 127 120 113 106 99 92 85 78 71 64 57 50 43 36 29 22 15 8 1)) (20 (134 127 120 ... context...: /Applications/Racket v8.2/collects/racket/private/map.rkt:257:2: gen-map /Users/Knoble/Library/Racket/8.2/pkgs/qi/flow.rkt:161:5 /Users/Knoble/Library/Racket/8.2/pkgs/memoize/memoize/main.rkt:71:19: count-generations /Users/Knoble/code/advent2021/day6/solution.rkt:59:0: count-all-generations /Applications/Racket v8.2/collects/racket/private/list.rkt:321:16: composed /Applications/Racket v8.2/collects/racket/cmdline.rkt:191:51 body of (submod "/Users/Knoble/code/advent2021/day6/solution.rkt" main) Even though I’m sure it’s a list. Lol. Whatever. Changing it anyway when I have time.


popa.bogdanp
2021-12-6 17:48:41

> Funny how your mind goes to a solution right away and how it influences things. The worst part is you just know it’s probably not that complicated and that you should just “reset”, but end up digging deeper instead. Or maybe that’s just me :smile:


popa.bogdanp
2021-12-6 17:50:40

So, my <https://github.com/Bogdanp/aoc2021/blob/master/day06.rkt|hash version> takes 220μs on my machine and I wanted to see how <https://github.com/Bogdanp/aoc2021/blob/f46abd0c2e23a502c4b1d7f26787af2147ccb330/day06-fxvector.rkt|an fxvector version> would fare. It does it in 11μs!


massung
2021-12-6 17:52:44

So, i was timing parsing, too. Here’s w/o the parsing: CL-USER&gt; (let ((ages (first (real-data #'parse-ages)))) (time (count-fish ages 256))) Evaluation took: 0.000 seconds of real time 0.000110 seconds of total run time (0.000109 user, 0.000001 system) 100.00% CPU 0 bytes consed


samdphillips
2021-12-6 18:23:12

I went straight to vector, but I didn’t try to solve before bedtime :smile:



joel
2021-12-6 22:17:00

In mine, for any given fish I calculated how many “1st gen spawns” would occur just using division, then did a recursive call for each spawned fish, using a hash to cache previously calculated answers. Finishes in < 1ms on my machine https://github.com/otherjoel/advent-of-code/blob/main/2021/day06.rkt\|https://github.com/otherjoel/advent-of-code/blob/main/2021/day06.rkt


massung
2021-12-6 22:25:17

@joel - that was my first solution as well


badkins
2021-12-7 01:19:44

I should’ve run raco fmt --help :) I’ll experiment with widths. Thanks for the tool @sorawee !


badkins
2021-12-7 01:24:06

I prefer: (~&gt; (file-&gt;string "day06.txt") string-trim (string-split ",") (map string-&gt;number _)) over the fmt reformatted: (~&gt; (file-&gt;string "day06.txt") string-trim (string-split ",") (map string-&gt;number _)) but I expect it’s impossible to please every one :)


sorawee
2021-12-7 01:54:09

This is using the default formatter. You can also write additional instruction to say that ~&gt; should be formatted that way, and it will always format the code that way.


badkins
2021-12-7 01:58:31

Interesting @samdphillips - I looked in the vector doc for a vector-update! - I see you just coded your own :)


samdphillips
2021-12-7 02:01:20

I don’t know why there isn’t a version in the stdlib


sorawee
2021-12-7 02:01:35

See how to use the API to write this additional instruction at https://docs.racket-lang.org/fmt/, but note that the interface is unstable.


sorawee
2021-12-7 02:06:51

#lang racket (require fmt) (define code #&lt;&lt;EOF (~&gt; (file-&gt;string "day06.txt") string-trim (string-split ",") (map string-&gt;number _)) EOF ) (define (my-formatter-map s) (case s [("~&gt;") (standard-formatter-map "require")] ; format `~&gt;` like how we format `require` [else #f])) (display (program-format code #:formatter-map my-formatter-map)) results in:

(~&gt; (file-&gt;string "day06.txt") string-trim (string-split ",") (map string-&gt;number _))


badkins
2021-12-7 02:32:10

Ok, I spent way too much time refactoring my solution today, so I’d like some feedback from fellow Racketeers re: the readability of <https://github.com/lojic/LearningRacket/blob/master/advent-of-code–2021/solutions/day06/day06.rkt|this solution> - does it seem reasonable to you?


badkins
2021-12-7 02:33:15

(credit for using vector-update! goes to Sam :) )


badkins
2021-12-7 02:34:15

Cool - thanks!


ben.knoble
2021-12-7 02:52:35

Assuming iterate f n x computes f^n(x), yeah, I think that’s quite readable. I might put the vrs on separate lines so it’s easy to spot differences at a glance.


massung
2021-12-7 03:10:43

Knowing the solution obviously helps w/ readability. The real question is can someone who knows the problem, but is looking at your solution to learn how to do it, able to follow?

The threading is nice. I think the vector iteration (line 15) would be confusing, though.

Side note: I’m always a bit confounded as to why racketeers use define lexically instead of let and lambda :slightly_smiling_face:


joel
2021-12-7 03:12:23

Personally I do it because it often avoids a needless level of nesting/left-drift.


massung
2021-12-7 03:14:03

Coming from CL originally, seeing define lexically feels like (although it absolutely isn’t) a code smell. Since in CL defun is a macro that expands to global scope. I have to double and triple-take every lexical define in Racket.


joel
2021-12-7 03:17:07

I get that and I’ve evolved at least an instinct to tuck everything away like that. I’m trying to find the passage (it might have been something of Matthew Butterick’s) that tipped me in favor of the clarity of lexical define early on.


badkins
2021-12-7 03:50:33

@massung I usually use let way more than define compared to most Racket folks. Not exactly sure why I used define for vr


badkins
2021-12-7 03:51:20

I like being able to select the entire let as a unit i.e. the variables and code that uses the variables


badkins
2021-12-7 03:52:34

@massung good point about separate lines for the vr clauses. I know it’s silly, but when coding up solutions for things like AoC, I think I subconsciously always try to minimize line count


badkins
2021-12-7 03:59:10

I replaced the define with a let. I tried separate lines for all the vr clauses, and I couldn’t accept that much vertical space :) Also, the function returns a single vector, and that line seems similar to a vector literal e.g. #(0 1 2 3 4 5 6 7 8) so I think I’m ok with it.


massung
2021-12-7 06:54:58

Day 7 spoilers



massung
2021-12-7 06:58:49

Longer than it needs to be. Brute force is quick enough, assuming summations are computed instead of looped. But I wanted to be a bit more elegant, so I treated the problem like a normal distribution and basically only checked targets within [-z,+z] and it dramatically sped up. Using z=0.5 worked for all data. On the real data I could take it all the way to z=0.1 and get the right answer and the time went down to a couple ms.


massung
2021-12-7 07:00:44

I’d be interested in other ideas people had for minimizing the search space.