Advent of Code 2022

Let’s do this thing!

I’m going to try Rust this time, since it’s 1) awesome 2) fast and 3) crazy. :D

Let’s see how it goes!

If you’d like to see the full form of any particular solution, you can do so on GitHub (including previous years and possibly some I haven’t written up yet): jpverkamp/advent-of-code

Here’s a full list of all of the posts:

So far, I have a few helper functions that all solutions can use:

Reading a file of input into a vector of lines

pub fn read_lines(filename: &Path) -> Vec<String> {
    let file = File::open(filename).expect("no such file");
    let buf = BufReader::new(file);

    buf.lines()
        .map(|l| l.expect("Could not parse line"))
        .collect()
}

Running a function as ‘main’

type FnPart = fn(&Path) -> String;

pub fn aoc_main(part1: FnPart, part2: FnPart) {
    let part = env::args()
        .nth(1).expect("first arg should be part (1 or 2)")
        .parse::<u32>().expect("part must be a non-negative integer");

    if part != 1 && part != 2 {
        
    }

    let filename = env::args().nth(2).expect("second arg should be input filename");
    let path = Path::new(&filename);
    if !path.exists() {
        panic!("{:?} does not exist", filename);
    }

    let now = Instant::now();
    let result = match part {
        1 => part1(path),
        2 => part2(path),
        _ => panic!("part must be 1 or 2")
    };
    let elapsed = now.elapsed();

    println!("{}", result);
    println!("took {:?}", elapsed);
}

This will allow me to have bin/day**.rs with a main function:

fn main() {
    aoc_main(part1, part2);
}

I may macro that. We’ll see.

Running test cases

Given the day (or input filename), function, and expected answer, we can automatically write the body of tests:

pub fn aoc_test(day: &str, f: FnPart, expected: &str) {
    let mut filename = String::from("data/");
    filename.push_str(&day);
    filename.push_str(".txt");

    let actual = f(Path::new(filename.as_str()));

    assert_eq!(expected, actual);
}

Likewise, the tests become:

#[cfg(test)]
mod tests {
    use aoc::aoc_test;
    use crate::{part1, part2};

    #[test]   
    fn test1() { aoc_test("01", part1, "70369") }

    #[test]
    fn test2() { aoc_test("01", part2, "203002") }
}

Previous solutions

And here are my previous year’s solutions: