/aoc19

Advent of Code 2019

Primary LanguageRust

Advent of Code 2019

My solutions to the 2019 Advent of Code edition in Rust.

I am a Rust noob so I am probably going to do these challenges using the following process:

  1. Write an ugly and inefficient solution that works.
  2. Look at other people's solutions to shamelessly copy learn and be inspired by their code.
  3. Rewrite my solutions.

To run the code for a solution just jump into a directory and build/run it:

$ cd day01
$ cargo run --release < input/input.txt

The solutions include tests. To run all of them quickly you can do something like:

$ for f in day??/Cargo.toml; do cargo test --release --manifest-path=$f; done

Inspiration

Stuff Learned

Day 1

Saturating arithmetic operations is much sexier than manually checking for and handling over-/underflow.

Use the successors function to create an iterator where each successive item is computed based on the preceding one.

Use filter_map to, well, filter and map. Very useful with ok which converts a Result<T, E> into Option<T> (and thus dicarding the error).

Day 2

Mainly: don't overengineer! Apart from that I didn't see any major differences (that I liked) in other people's solutions.

A small thing I learned was using &[T] over &Vec<T> in function parameters. The only time you want to use &Vec<T> is if you for some reason need to read the vector's capacity. If you want to change the vector you'd have to use &mut Vec<T> anyway (ref. Steve Klabnik).

Day 3

Improved performance quite a bit by using HashSet (and the intersection method) instead of Vec.

Learned to implement the Hash and PartialEq traits.

Still not sure about Eq vs PartialEq and Ord vs PartialOrd. Probably need to see it more in the wild to understand when and why to use them.

Some other subjects that still are fuzzy: reference vs value, iter vs into_iter, all the different ok, ok_or, or_else, ok_or_else, unwrap_or, unwrap_or_else, etc. Probably mixing Option and Result here.

Lifetimes are still pretty much terra incognita so I basically try avoid them for now. Same for all that trait stuff in functions (apparently they are called bounds).

Day 4

Found a great answer on StackOverflow on how to return an Iterator from a function. To summarize: use impl trait or Box (if the return type is decided dynamically). Can also use newtype or type aliases.

Day 5

Day 6

Day 7

Use Default. Itertools for permutations and other cool functional stuff which aren't in the std yet.

Was a simple answer on the iter vs into_iter on StackOverflow:

  • iter() iterates over the items by reference
  • into_iter() iterates over the items, moving them into the new scope
  • iter_mut() iterates over the items, giving a mutable reference to each item

But looking at other answers it seems to be at bit more complicated (and context dependent).