diff --git a/2022/rust/.gitignore b/2022/rust/.gitignore new file mode 100644 index 0000000..eb5a316 --- /dev/null +++ b/2022/rust/.gitignore @@ -0,0 +1 @@ +target diff --git a/2022/rust/Cargo.lock b/2022/rust/Cargo.lock new file mode 100644 index 0000000..d37200f --- /dev/null +++ b/2022/rust/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aoc2022" +version = "0.1.0" diff --git a/2022/rust/Cargo.toml b/2022/rust/Cargo.toml new file mode 100644 index 0000000..8c69839 --- /dev/null +++ b/2022/rust/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "aoc2022" +version = "0.1.0" + +[[bin]] +name = "day1" +path = "src/day1.rs" + +[[bin]] +name = "day2" +path = "src/day2.rs" + +[dependencies] diff --git a/2022/rust/fetch_input.sh b/2022/rust/fetch_input.sh new file mode 100755 index 0000000..0855a9c --- /dev/null +++ b/2022/rust/fetch_input.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env sh + +AOC_YEAR="${AOC_YEAR:-2022}" +if [ "$#" -lt 1 ]; then + echo "Error: No day provided" + exit 1 +fi +DAY="$1" +f="$HOME/.cache/aoc$AOC_YEAR/$DAY.input" +if [ -f "$f" ]; then + echo "Skip: File already exists" + exit 0 +fi +url="https://adventofcode.com/$AOC_YEAR/day/$DAY/input" +cookie="$(cat "$HOME/.advent-of-code-auth-cookie")" +if curl --fail-with-body -X GET "$url" -H "Cookie:$cookie" > "$f"; then + echo "Downloaded $url to $f" + exit 0 +else + echo "Error: curl failed" + rm -f "$f" + exit 1 +fi \ No newline at end of file diff --git a/2022/rust/readme.md b/2022/rust/readme.md new file mode 100644 index 0000000..8a76e0d --- /dev/null +++ b/2022/rust/readme.md @@ -0,0 +1,39 @@ +# Rust Advent of Code 2022 Solutions + +I've been writing more Rust this year for an internal tool at work and have +really enjoyed the tooling. I intent to do more with Rust this year than +last and aim for good performance (without bending over too far backwards, +anyways...) + +## Running + +First, you will want to fetch your input for the day you want to run. You will +need `curl` and your Advent of Code cookie in `~/.advent-of-code-session-cookie` +to run the following script: + +```bash +fetch_input.sh 1 +``` + +Where `1` is the day's input you want to fetch. + +### Debug + +```bash +cargo run --bin day1 +``` + +### Tests + +```bash +cargo test --bin day1 +``` + +### Release Mode + +For speeeeeed! + +```bash +cargo build --release --bin day1 +time ./target/release/day1 +``` diff --git a/2022/rust/src/common.rs b/2022/rust/src/common.rs new file mode 100644 index 0000000..4c879da --- /dev/null +++ b/2022/rust/src/common.rs @@ -0,0 +1,11 @@ +use std::env::var as envvar; +use std::fs; +use std::path::Path; + +pub fn day_input(day: u8) -> String { + let home = &envvar("HOME").unwrap(); + let home_path = Path::new(home); + let path_buf = home_path.join(format!("./.cache/aoc2022/{0}.input", day)); + let file_path = path_buf.to_str().unwrap(); + fs::read_to_string(file_path).unwrap() +} diff --git a/2022/rust/src/day1.rs b/2022/rust/src/day1.rs new file mode 100644 index 0000000..632b42a --- /dev/null +++ b/2022/rust/src/day1.rs @@ -0,0 +1,64 @@ +mod common; + +fn main() { + let calories = ordered_calories(&common::day_input(1)); + println!("Part 1: {}", part1(&calories)); + println!("Part 2: {}", part2(&calories)); +} + +fn ordered_calories(input: &str) -> Vec { + let mut result = Vec::from([0_i32]); + for l in input.lines() { + if l.trim() == "" { + result.push(0); + } else { + if let Ok(v) = l.parse::() { + *(result.last_mut().unwrap()) += v; + } + } + } + result.sort_by(|a, b| b.partial_cmp(a).unwrap()); + result +} + +fn part1(calories: &Vec) -> i32 { + calories[0] +} + +fn part2(calories: &Vec) -> i32 { + calories.iter().take(3).sum() +} + +#[cfg(test)] +mod tests { + use super::*; + + const TEST_INPUT: &str = "1000 +2000 +3000 + +4000 + +5000 +6000 + +7000 +8000 +9000 + +10000"; + + fn test_calories() -> Vec { + ordered_calories(TEST_INPUT) + } + + #[test] + fn test_part1() { + assert_eq!(part1(&test_calories()), 24000) + } + + #[test] + fn test_part2() { + assert_eq!(part2(&test_calories()), 45000) + } +}