diff options
author | Toby Vincent <tobyv13@gmail.com> | 2022-12-04 10:02:53 -0600 |
---|---|---|
committer | Toby Vincent <tobyv13@gmail.com> | 2022-12-04 10:02:53 -0600 |
commit | 766b6af513ea1961cc1d657fef39ee03374a4d5b (patch) | |
tree | 981b76b98e01b4b2e856bb3c031b2e5bbe18c068 /src | |
parent | e3c690ef6ac8a9ea816a474d37f77ced64a9ac12 (diff) |
feat: impl day 2
Diffstat (limited to 'src')
-rw-r--r-- | src/day_1.rs | 29 | ||||
-rw-r--r-- | src/day_2.rs | 168 | ||||
-rw-r--r-- | src/lib.rs | 4 | ||||
-rw-r--r-- | src/main.rs | 29 |
4 files changed, 207 insertions, 23 deletions
diff --git a/src/day_1.rs b/src/day_1.rs new file mode 100644 index 0000000..6e04a6a --- /dev/null +++ b/src/day_1.rs @@ -0,0 +1,29 @@ +use anyhow::Result; + +pub fn day_1() -> Result<()> { + let input = include_str!("../input/day_1.txt"); + println!("day 1"); + println!("part 1: {}", part_1(input)); + println!("part 2: {}", part_2(input)); + + Ok(()) +} + +pub fn part_1(input: &str) -> usize { + input + .split("\n\n") + .map(|e| e.split('\n').flat_map(|l| l.parse::<usize>()).sum()) + .max() + .unwrap() +} + +pub fn part_2(input: &str) -> usize { + let mut vec = input + .split("\n\n") + .map(|e| e.split('\n').flat_map(|l| l.parse::<usize>()).sum()) + .collect::<Vec<usize>>(); + + vec.sort_unstable(); + + vec.iter().rev().take(3).sum() +} diff --git a/src/day_2.rs b/src/day_2.rs new file mode 100644 index 0000000..019e745 --- /dev/null +++ b/src/day_2.rs @@ -0,0 +1,168 @@ +use std::str::FromStr; + +use anyhow::{anyhow, Result}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +struct Game { + shapes: (Shape, Shape), + outcome: Outcome, + score: usize, +} + +impl Game { + fn new(a: Shape, b: Shape, outcome: Outcome) -> Self { + Self { + shapes: (a, b), + outcome, + score: b as usize + outcome as usize, + } + } +} + +impl From<(Shape, Shape)> for Game { + fn from((a, b): (Shape, Shape)) -> Self { + Self::new(a, b, (a, b).into()) + } +} + +impl From<(Shape, Outcome)> for Game { + fn from((a, outcome): (Shape, Outcome)) -> Self { + Self::new(a, (a, outcome).into(), outcome) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(u8)] +enum Outcome { + Loss = 0, + Draw = 3, + Win = 6, +} + +impl From<(Shape, Shape)> for Outcome { + fn from((a, b): (Shape, Shape)) -> Self { + match (a, b) { + (Shape::Rock, Shape::Rock) => Outcome::Draw, + (Shape::Rock, Shape::Paper) => Outcome::Win, + (Shape::Rock, Shape::Scissors) => Outcome::Loss, + (Shape::Paper, Shape::Rock) => Outcome::Loss, + (Shape::Paper, Shape::Paper) => Outcome::Draw, + (Shape::Paper, Shape::Scissors) => Outcome::Win, + (Shape::Scissors, Shape::Rock) => Outcome::Win, + (Shape::Scissors, Shape::Paper) => Outcome::Loss, + (Shape::Scissors, Shape::Scissors) => Outcome::Draw, + } + } +} + +impl FromStr for Outcome { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + match s { + "X" => Ok(Outcome::Loss), + "Y" => Ok(Outcome::Draw), + "Z" => Ok(Outcome::Win), + s => Err(anyhow!("Unknown symbol: {}", s)), + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum Shape { + Rock = 1, + Paper = 2, + Scissors = 3, +} + +impl From<(Shape, Outcome)> for Shape { + fn from((shape, outcome): (Shape, Outcome)) -> Self { + match (shape, outcome) { + (Shape::Rock, Outcome::Draw) => Shape::Rock, + (Shape::Rock, Outcome::Win) => Shape::Paper, + (Shape::Rock, Outcome::Loss) => Shape::Scissors, + (Shape::Paper, Outcome::Loss) => Shape::Rock, + (Shape::Paper, Outcome::Draw) => Shape::Paper, + (Shape::Paper, Outcome::Win) => Shape::Scissors, + (Shape::Scissors, Outcome::Win) => Shape::Rock, + (Shape::Scissors, Outcome::Loss) => Shape::Paper, + (Shape::Scissors, Outcome::Draw) => Shape::Scissors, + } + } +} + +impl FromStr for Shape { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + match s { + "A" | "X" => Ok(Shape::Rock), + "B" | "Y" => Ok(Shape::Paper), + "C" | "Z" => Ok(Shape::Scissors), + s => Err(anyhow!("Unknown symbol: {}", s)), + } + } +} + +pub fn day_2() -> Result<()> { + let input = include_str!("../input/day_2.txt"); + + println!("day 2"); + println!("part 1: {}", part_1(input)?); + println!("part 2: {}", part_2(input)?); + + Ok(()) +} + +pub fn part_1(input: &str) -> Result<usize> { + input.lines().try_fold(0, |acc, l| { + let (a, b) = l + .split_once(' ') + .ok_or_else(|| anyhow!("Missing deliminator"))?; + + let a: Shape = a.parse()?; + let b: Shape = b.parse()?; + let game: Game = (a, b).into(); + + Ok(acc + game.score) + }) +} + +pub fn part_2(input: &str) -> Result<usize> { + input.lines().try_fold(0, |acc, l| { + let (a, outcome) = l + .split_once(' ') + .ok_or_else(|| anyhow!("Missing deliminator"))?; + + let a: Shape = a.parse()?; + let outcome: Outcome = outcome.parse()?; + let game: Game = (a, outcome).into(); + + Ok(acc + game.score) + }) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part_1_example() -> Result<()> { + let input = "A Y +B X +C Z"; + + assert_eq!(15, part_1(input)?); + Ok(()) + } + + #[test] + fn test_part_2_example() -> Result<()> { + let input = "A Y +B X +C Z"; + + assert_eq!(12, part_2(input)?); + Ok(()) + } +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..e72712b --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,4 @@ +use std::{fs::File, io::BufReader}; + +pub mod day_1; +pub mod day_2; diff --git a/src/main.rs b/src/main.rs index 8750800..e802784 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,26 +1,9 @@ -fn main() { - let input = include_str!("../input/day_1.txt"); - println!("day 1, part 1: {}", day_1::part_1(input)); - println!("day 1, part 2: {}", day_1::part_2(input)); -} - -mod day_1 { - pub fn part_1(input: &str) -> usize { - input - .split("\n\n") - .map(|e| e.split('\n').flat_map(|l| l.parse::<usize>()).sum()) - .max() - .unwrap() - } - - pub fn part_2(input: &str) -> usize { - let mut vec = input - .split("\n\n") - .map(|e| e.split('\n').flat_map(|l| l.parse::<usize>()).sum()) - .collect::<Vec<usize>>(); +use advent_of_code_2022::{day_1, day_2}; +use anyhow::Result; - vec.sort_unstable(); +fn main() -> Result<()> { + day_1::day_1()?; + day_2::day_2()?; - vec.iter().rev().take(3).sum() - } + Ok(()) } |