All programs take in their input as stdin
Example for day 1:
cargo run --bin day01 < data/01
Naive algorithm: Iterate over array in 2 nested loops: O(n^2) Optimizations discussed in part 2
Naive algorithm: Iterate over array in 3 nested loops: O(n^3) Optimizations:
- Iterate i from 0 until n, j from 0 until i, and k from 0 until j
- Sort the array initially (Initial O(n log n) cost)
- Use binary search in the innermost loop: O(n^2 log n)
-
- This implies part 1 can be solved in O(n log n)
- Keep track of when the sum becomes too large, as each outer loop increases the number, keeping track of where the sum exceeded 2020 provided an upper bound for future loops
Easy string parsing problem
Optimizations:
- Stop counting if over the maximum value given
Nothing special, easier than part 1
Just an array indexing problem
Optimizations:
- Use modulo indexing instead of generating the list many times (why would you do this)
Just part 1 with a for loop
Just parsing.
I used a scan
iterator and a horrendous Option<Result<Option<T>, _>>
return type combined with a filter_map
to iterate over the lines while allowing for less than 1 output per line. scan
's accumulator allowed me to build up passports and validate them. Some(Ok(None))
means a line parsed and either no new passport was generated or one was, and it turned out to be missing fields. In general, filter_map
worked nicely for this problem
Just another chain onto part 1.
Another iterator chain
Keep track of min and max for part 2. Easy stuff
I use a tightly packed bit array to store seat state. After padding the left and right seats to mark all remaining seats in a row occupied, all I have to do is check for a position where the row is not equal to 0xFF. I can use the trailing_ones
function to find the position within that row, which probably compiles down to some processor intrinsic.
Just set operations
- Union all the sets in a group
- Take the resulting set's length
- Add up all lengths
Optimizations:
- Represent sets as bool arrays
- Can probably store the scan state in a 64 bit integer, but state isn't getting copied a lot so probably not worth it
- Intersection of all sets in a group
- Take resulting set's length
DAG recursion
Look through the DAG recursively for membership
Optimizations:
- Stop checking as soon as a bag's sub-bag contains our target bag
- Use
HashMap<String, Vec<(String, usize)>>
as data structure for rules. Linear search is better for smaller sizes than going through a whole hash - NYI: Caching / memoization
Count subentries in the DAG recursively
Optimizations:
- NYI: Caching / memoization
Assembly-like
Just run the code.
Optimizations
- Use a
Vec<bool>
to keep track of previously run lines, which should be the best data structure
Run the code, flipping each flippable operator. This one could be made much more complicated with control flow, but it turns out brute force is easy and works well. Optimizations:
- Reuse code array, and mutate instructions in place, flipping them back when we've finished testing
- Stop early if we find an answer, of course