
@me1890 feel free to check out <https://github.com/lojic/LearningRacket/tree/master/advent-of-code–2020|my Racket solutions>. I’m planning on going to the end, but this is my first time, so I’m not sure what to expect time-wise later on. A caveat, for a few, I coded similarly to the way I might code professionally, but for many, I went for conciseness. In other words, there may be some ideas in my solutions for “fun programming”, but not so much for idiomatic Racket code :) For an extreme example, I’ll put Day 9, Part 2 in a thread (to avoid spoilers). I first coded “reasonably” with separate, testable, functions, then for fun, I just collapsed everything into one function (which I would not want to modify!) :)

Day 9 Part 2 (being concise): (define (run n fname)
(let ([ r (let find-range ([lst (map string->number (file->lines fname))])
(or (let loop ([lst lst][sum 0][result '()])
(cond [ (= sum n) result ]
[ (or (> sum n) (null? lst)) #f ]
[ else (let ([ x (car lst) ])
(loop (cdr lst) (+ sum x) (cons x result))) ]))
(find-range (cdr lst)))) ])
(+ (apply min r) (apply max r))))

(module+ test
(require rackunit)
(check-equal? (run 127 "day09-test.txt") 62)
(check-equal? (run 20874512 "day09.txt") 3012420))

To be frank, the fun of golfing a bit has worn off, so I may do the remainder in a manner that more easily allows reading/comprehending, modifying & testing :)

Thanks, that was informative. I’ve noticed that everyone here as their days split into files, but I have all of my code in one file. Is there a reason (other than organizational preference) to split the solutions between files?

hi! I literally had to learn racket idioms as I go (racket docs are amazing!) so it is very interesting to compare them to your Professional-ish racket code :slightly_smiling_face:
so thanks!

@keith047 has joined the channel

Hi everyone. I have fond memories of using Scheme many years ago in school, so I decided to solve the AoC problems this year in racket.

But I do most of my day-to-day work in typescript, so I have been running through the problems as fast as I can in JS, and then going back and using racket.

is the leaderboard key anywhere? I can’t see the history for last year.

It’s in the topic

:stuck_out_tongue: I feel so smart.

wow - racket has really great participation. The other leaderboard I’m on is from the TS discord, which I think is a much larger community, and there aren’t half as many people on the leaderboard.

I’m on a leaderboard for my university and we have just 4 active players, but it’s fun to compare solutions between languages (each of us is using a different language, Racket, C, Haskell, and Python)

I did racket only for like the first five days, but I would spend so much time trying to find the right functions, and my pride was hurting because some of those people in the other group can crank out some dirty JS blindingly fast, so I switched to JS first.

But the questions are released at midnight where I am, and my brain doesn’t work that great by then, so I’ve found I’m not that much faster with the languages I use every day :slightly_smiling_face:

I do some very crappy racket at first, then i spend time making my solution better (be it more readable or faster)

I’ve only done AoC once before (last year) and only for a like the first week.

But my impression is that the problems are much less time-consuming and/or easier this year. The stats for completion seem to back that up.

Many of these seem to be typing speed contests.

I only did the first few problems last year, but i have a lot more free time this year, so i’m hoping to get to the end. From what i’ve heard on reddit, the problem descriptions and example inputs appear to be a higher quality.

I think that if I actually knew racket well, I could be quick, because it’s so expressive relatively.

Not just speed typing contest, but also choseing the best language for a quick solution. I’ve noticed a lot of the very fast ones have been in ruby and python.

But my impression is also that efficiency is not really an issue with these problems. Until it is :slightly_smiling_face: So I’m not optimizing anything really.

that makes sense.

The highest rank I got was 870 on day day 6.

If you want more language comparison, here’s SML: https://github.com/benknoble/advent2020

My solution for day 9 took about 10 seconds to run, while my one of the other people’s solutions took about 150ms (in C), so I decided to take it as a fun exercise in optimization, and got mine down to 25ms.

That seems slow for C? I gotta translate mine to racket and see how it runs.

That looks interesting, thanks!

It was pretty slow, he got it down to 8ms after a bit more optimization for himself.

But yeah, there are a couple of guys in the TS group that have cracked the top 100, and are consistently in that ballpark. And one or two that are in the top 1000 every day. I haven’t cracked 1000 yet :slightly_smiling_face:

but they do…dirty things to achieve such results.

Wow, that’s impressive. I’m only doing the challenges with competitive speed as my second priority. Before advent of code, I knew very little racket, and I wanted to learn, so this is how I’m learning Racket.

I find it to be a nice language for competitive programming like this.

Day 9 in SML: ~800 _micro-_seconds for part1, ~900 for part2. The only “optimization” I applied was a good use of sets/queues, and an efficient contiguous-subsequence algorithm. Well, that, and tail recursion :slightly_smiling_face:

@me1890 re: separate files, I just like starting with a clean slate each time, so I suppose it is organization preference. At the beginning, I thought I’d be reusing some functions as I went along, so I created advent.rkt
, but I think I only used it on days 1 & 2, and then just skipped it. There is something pleasing about reading the day’s puzzle, and then opening a new file and typing #lang racket
w/o any pre-existing code cluttering up the file :)

By the way @me1890, if you back up one directory to https://github.com/lojic/LearningRacket you’ll find quite a bit of code you can take a look at that could be helpful as you learn Racket.

oh nice, a few of the project euler problems. I love that website. I’ve have about 35 of the problems solved in rust.

For the http://exercism.io\|exercism.io directory, a friend was doing it in Elixir, so I was curious how easy it would be to port his Elixir solutions to Racket. It was surprisingly easy - the languages are much more similar than it might seem.

Interesting, elixir is erlang an erlang based language, right?

Kind of a functional Ruby-ish language on top of Erlang I guess.

I love SML @ben.knoble - you got a link?

I wish Advent of Code did a better job of allowing us to check out solutions - e.g. an easy way to “show me <language> solutions for day <n>”. I’ve got my own list of a few github directories, but it was a bit of a pain to put it together, and now many of the directories are stalled at various days.

Some people publish their answers right away - I’m not a fan of that, IMO you should at least wait a day. But there’s no way for AoC to know what language is used…after all, you just plug in the answer.

On the advent of code subreddit, they have a solutions megathread each day that gathers A few hundred to a thousand solutions every day. Here’s todays: https://www.reddit.com/r/adventofcode/comments/k9lfwj/2020_day_09_solutions/

$ racket day09.rkt
took 433µs
took 900µs
:smile:

Nice!


You might find https://github.com/bogdanp/awesome-advent-of-code\|this helpful. All the links are self-reported every year (apart from this year’s Racket ones which I’ve added myself from this channel). It goes back to 2018, but the PR volume this year has been crazy… I’ve been merging ~50PRs per day for the past week.

<https://github.com/tckmn/polyaoc–2020|This person> is currently #6 on the leaderboard, and has been publishing solutions in multiple languages, and some of them are really good. They added Racket for Day 9, and their solution was almost identical to my original, but they combined my two functions into one elegantly, so I made the same adjustment. I’ll put it in a thread…

(define (validate [ lst (map string->number (file->lines "day09.txt")) ])
(let ([ x (list-ref lst 25) ])
(if (member x (map (curry apply +) (combinations (take lst 25) 2))) (validate (cdr lst)) x)))

vs. my original: (define (validate n lst)
(let ([ x (list-ref lst n) ])
(if (member x (map (curry apply +) (combinations (take lst n) 2))) #f x)))
(define (xmas n fname)
(let loop ([ lst (map string->number (file->lines fname)) ])
(or (validate n lst) (loop (cdr lst)))))

Awesome - thanks!


Just out of curiosity, why do you dislike people publishing solutions right away? I figure most people are doing this for fun, and if people are trying to score well, cheating by using someone else’s solution would result in a much lower score by coming in later. I mainly want to see other solutions to expand my thinking about approaches to the problem.

Yeah I didn’t say I was rational :slightly_smiling_face:

It’s kinda like back in the day I refused to help people with homework problems. I’ve mellowed on that a lot, because I’ve come to the conclusion that learning is more important than grades.

Gotcha. I would like to think that people only look at solutions after they create their own, or if they’re totally stuck and have given up.

I just don’t want to look at anyone else’s answers until I’ve solved a thing, but at that point it’s extremely useful for learning to see as many solutions as possilbe.

Totally agree.

It really is fascinating to see various approaches. I’ve been programming professionally for over 30 years, and I’ve still learned a lot through this Advent of Code game :)

There are some sites with programming challenges that I use mainly to help motivate learning new languages. I really like when after you’ve solved a problem it shows you answers in the same language.

Wow

That’s pretty incredible @popa.bogdanp!

Naturally I’m biased, but I do think the Racket solutions, both mine & others, have done relatively well compared to many other languages. I looked through the 3 Julia directories you have, and I wasn’t impressed. I’m pretty sure Julia can do reasonably well, so I may port my Racket solutions to Julia if I have time, as a way to learn Julia better. It seems to be a nice language to complement Racket. I’ll probably only use it for math-heavy code that I need to be super fast - without having to bang my head against C++ :)

Wow, that same person put this Ruby line together as the complete solution to Day 9 Part 1: val = (File.readlines('input').map &:to_i).each_cons(26).find{\|*a, n\| !a.combination(2).map(&:sum).include?(n)}.last

They definitely have some coding chops.

aw snap, there’s a curry
in racket? I feel so dumb now.

I had seen cut
in some SRFI or whatever those are. That’s way better.

Just for fun, here’s a much faster version of their solution: #lang racket/base
(require racket/file racket/list racket/vector)
(define input (time (list->vector (file->list "input"))))
(define (part1 input i)
(define v (vector-ref input (+ i 25)))
(cond [(for/or ([k (in-combinations (vector->list (vector-copy input i (+ i 25))) 2)])
(= v (+ (car k) (cadr k))))
(part1 input (add1 i))]
[else v]))
(define (part2 input val)
(define (helper i val num sum)
(cond
[(< sum val) (helper i val (add1 num) (+ sum (vector-ref input (+ i num))))]
[(> sum val) (helper (+ i 1) val (sub1 num) (- sum (vector-ref input i)))]
[else (let ([slice (vector->list (vector-copy input i (+ i num)))])
(+ (apply min slice) (apply max slice)))]))
(helper 0 val 0 0))
(define val (time (part1 input 0)))
val
(time (part2 input val))

@keith047 yes, curry
and curryr
which can be handy sometimes

Fo sho

@samth thanks, I’ll check that out. Thus far, I’ve purposely ignored efficiency completely. That goes against my nature, but it’s been fun :) Later, I may re-work some to be more efficient and then compare to Julia.

@samth intuitively, using list->vector
, vector-copy
, and then vector->list
doesn’t seem super efficient.

The real problem is that in-combinations
takes a list. I ran into that too.

I made some stylistic improvements @samth :) https://github.com/lojic/LearningRacket/blob/master/advent-of-code-2020/day09-samth.rkt

very neat puzzle today!

I definitely agree. It had a very elegant solution too.

some clever dynamic programming thing right? I didn’t do that at all for part 2 and did something much different

yup, i had an O(n) complexity dynamic programming solution

this is what I did: https://github.com/jackfirth/advent-of-code/blob/master/year2020/day10/part2.rkt

summary: I chopped the adaptor list up into subchains of 1-volt adaptors, since you can remove adaptors from each subchain without affecting the others

https://git.lain.faith/haskal/aoc2020/src/branch/aoc2020/10.rkt#L18
linear time by memoized “dfs” on a graph containing edges corresponding to the valid adapter connections, the “dfs” counts the paths to the last node. the code to build the graph was kind of spaghetti though