Spoiler Warning: If you want to solve the challenges by yourself, don't read the code.
This directory contains the code I used to solve the challenges from Advent of Code 2020.
This year I'm going with TypeScript using deno. Solutions can be run with ./main.ts, or run all days using for i in $(seq -f '%02g' 1 25); do cd "day$i"; ./main.ts; cd ..; done.
The following table lists the available solutions by day and language. I also added a short summary for each day.
- Deno seems great:
- I really like working with deno, and especially setting it up is a nice experience: you install a single binary for deno (and maybe the VS code extension) and already you get a fully working environment, and also a well equipped-one. Setting up similar tooling can get really annoying for node. For languages like Ruby it's almost impossible to get such a setup. We get:
- package management
- type checks
- linting
- formatting
- autocompletion
- automatic imports
- a basic testing framework
- with coverage reports
- debugger support
- documentation, e.g. here's the docs of the utils file I used for this year.
- Since 1.6 you can even export a standalone binary.
- Even though deno sometimes feels a bit "beta", I didn't encounter any severe problems. One thing I found a bit annoying is that the formatter sometimes removed big chunks of code, but I could always get them back with ⌘ Z.
- It feels great to be able to use all the latest language features and TypeScript consistently across the codebase (including e.g. tests) without having to set up many things. In fact, I have 0 config files, and the defaults always felt reasonable.
- I did not target browsers though... with those I think things would become more messy.
- I really like working with deno, and especially setting it up is a nice experience: you install a single binary for deno (and maybe the VS code extension) and already you get a fully working environment, and also a well equipped-one. Setting up similar tooling can get really annoying for node. For languages like Ruby it's almost impossible to get such a setup. We get:
- Types... there are pros and cons. Adding all the types feels a bit tedious form at times, but it makes up by catching so many small errors all the time:
- I feel TypeScript is a bit verbose sometimes, and certainly invites to over-engineer things to sprinkle everything with types. E.g. on day 12 I came up with a solution which works eerie similarly to this haskell one, but looks a lot more Java-ish...
- Adding all the types means writing more code and I guess does not make it easier to get to the leaderboard in the end.
- TypeScript is very clever and can figure out surprisingly many things at compile-time already. E.g. in this switch statement it knows that the variable is changed from
nullin all branches and that always one of thecasees is called, and would complain otherwise. - Since TS can figure out so many things it's frustrating when it can not, and you run into issues like inferring just one type parameter is not yet possible, or
Array.includescan not "filter" types.
- JavaScript (and thus also TypeScript) had a bad reputation for missing a good standard library. While it is not huge still, I found nowadays it comes reasonably equipped, especially for the kind of programming you tend to do for AoC. While things like classes, getters/setters, async, promises, generators are not so interesting, I used some new features extensively:
- From ES2015: string template literals, arrow functions, object destructuring and spreads,
Sets,String.startsWith,classes (only in day 11 though) - From ES2016
Array.includes - From ES2017
Object.values, and hey:String.padStartreplaces the infamousleft-pad - From ES2018 spreads and named capture groups
- From ES2019
Array.flatandArray.flatMap
- From ES2015: string template literals, arrow functions, object destructuring and spreads,
- I did end up writing a small library of things I found missing and would expect in a "JS standard library", like basic
sum,producthelpers, and some set operations. Implementing those was actually fun, because I could use some OOP, abstract base class, inheritance, getter methods, generators, iterators etc. which I normally try to avoid, as in high level React code they are usually unjustified complexity. - Seems like days 22, 18, 15, 12, 5 might be suitable for bf/piet
This is the 3rd year after 2015 and 2016 where I was able to complete all the puzzles in time 🎉🎄 I also started some of the riddles at 6am (MEZ) when they are released, but I could not make it to the leaderboard. To be fair there's around 10x more people competing this year compared to 2016 when I made it to the leaderboard a few times. I also tried to enjoy the process and that usually means not hurrying through it. Anyways, I was relatively fast on day 20, with spot 781 for part 1, and spot 743 for part two. And on day 8 I made spot 801 on part 2. Otherwise I was always above 1k.
I enjoy looking at how other coders solved the riddles to learn even more. This year I follow (A-Z):
- carlastabile (Ruby)
- cschell (Ruby)
- etrepum (PureScript & Dhall)
- fdlk (R)
- glguy (Haskell)
- senegalo (Ruby)
- sophiebits (Python)