Advent of Code 2021
This doc has my solutions for the 2021 Advent of Code. It assumes some familiarity with the Rust language.
Advent of Code gives all participants the same problems, but gives different inputs to each participant. Therefore, it makes little sense to give the actual numeric answers to problems here. However, we do provide the input that was given to us in order to contextualize the input-parsing code. The solutions below should work for any input/output pair provided by Advent of Code. |
This document has the solutions out in the open! Don’t read it if you’re still working on Advent of Code. |
Setup
Rust is a very strict language and makes you explicitly handle all errors that might arise (as opposed to, say, exceptions implicitly being thrown on error, as Python does).
However, we can trust our inputs, taken straight from Advent of Code, to be correct and give unambiguous answers without errors.
For this reason, we tend to be pretty loosey-goosey about unwrapping the Option
s and Result
s that the Rust compiler correctly points out we could theoretically encounter.
(There wouldn’t be any point to handling those cases gracefully; we’re just trying to solve Advent of Code, not create general-purpose a submarine-squid-bingo-player that can function sensibly even when the squid gives us nonsensical input.
For our purposes, the residual variants of a Try
object at the boundary of our program are !
(Rust’s bottom or “never” type).)
Commonly used code, in src/lib.rs
and src/utils.rs
, is below:
macro_rules! include_days {
($($mod_name:ident:$ft_name:literal),* $(,)?) => {
$(#[cfg(feature = $ft_name)] pub mod $mod_name;)*
};
}
include_days!(
day_01:"day_01",
day_02:"day_02",
day_03:"day_03",
day_04:"day_04",
day_05:"day_05",
day_06:"day_06",
day_07:"day_07",
day_08:"day_08",
day_09:"day_09",
day_10:"day_10",
day_11:"day_11",
day_12:"day_12",
day_13:"day_13",
day_14:"day_14",
day_15:"day_15",
day_16:"day_16",
day_17:"day_17",
day_18:"day_18",
day_19:"day_19",
day_20:"day_20",
day_21:"day_21",
day_22:"day_22",
day_23:"day_23",
day_24:"day_24",
day_25:"day_25",
);
pub(crate) fn to_decimal<V: AsRef<[bool]>>(binary_digits_msbf: V) -> u32 {
binary_digits_msbf
.as_ref()
.iter()
.rev()
.enumerate()
.map(|(pow2, &is_on)| u32::from(is_on) * 2u32.pow(u32::try_from(pow2).unwrap()))
.reduce(|a, b| a + b)
.unwrap_or(0)
}
pub(crate) fn to_big_decimal<V: AsRef<[bool]>>(binary_digits_msbf: V) -> u64 {
binary_digits_msbf
.as_ref()
.iter()
.rev()
.enumerate()
.map(|(pow2, &is_on)| u64::from(is_on) * 2u64.pow(u32::try_from(pow2).unwrap()))
.reduce(|a, b| a + b)
.unwrap_or(0)
}
pub(crate) fn abs_diff(a: usize, b: usize) -> usize {
if a > b {
a - b
} else {
b - a
}
}