diff options
author | cos <cos> | 2022-12-04 17:32:57 +0000 |
---|---|---|
committer | cos <cos> | 2022-12-05 11:14:34 +0000 |
commit | 002f3d163bd606434d5e73e1658caad29690f03b (patch) | |
tree | bed020ea4991845b5b59b2179a6b17c3d7328c3b | |
parent | 5886b1144dac92767b49028bd0d7093667fdafb3 (diff) | |
download | adventofcode-002f3d163bd606434d5e73e1658caad29690f03b.zip |
Add day02, 2022
-rw-r--r-- | 2022/rust/Cargo.toml | 2 | ||||
-rw-r--r-- | 2022/rust/day02/Cargo.toml | 8 | ||||
-rw-r--r-- | 2022/rust/day02/src/main.rs | 127 |
3 files changed, 136 insertions, 1 deletions
diff --git a/2022/rust/Cargo.toml b/2022/rust/Cargo.toml index 079c5ee..0707ddf 100644 --- a/2022/rust/Cargo.toml +++ b/2022/rust/Cargo.toml @@ -1,7 +1,7 @@ [workspace] members = [ "day01", -# "day02", + "day02", # "day03", # "day04", # "day05", diff --git a/2022/rust/day02/Cargo.toml b/2022/rust/day02/Cargo.toml new file mode 100644 index 0000000..9377f12 --- /dev/null +++ b/2022/rust/day02/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "day02" +version = "0.1.0" +edition = "2021" + +[dependencies] +aoc = { path = "../../../common/rust/aoc" } +anyhow = "1.0" diff --git a/2022/rust/day02/src/main.rs b/2022/rust/day02/src/main.rs new file mode 100644 index 0000000..d98d7b1 --- /dev/null +++ b/2022/rust/day02/src/main.rs @@ -0,0 +1,127 @@ +use { + anyhow::{ + anyhow, + Context, + Result, + }, + std::{ + env::args, + fs::File, + io::{ + BufRead, + BufReader, + }, + path::Path, + }, +}; + +#[derive(Clone,Copy)] +enum Play { + Rock = 1, + Paper = 2, + Scissors = 3, +} + +impl Play { + fn strategy(&self, desired: Outcome) -> Play { + match (self, desired) { + (Play::Rock, Outcome::Lose) => Play::Scissors, + (Play::Rock, Outcome::Draw) => Play::Rock, + (Play::Rock, Outcome::Win) => Play::Paper, + (Play::Paper, Outcome::Lose) => Play::Rock, + (Play::Paper, Outcome::Draw) => Play::Paper, + (Play::Paper, Outcome::Win) => Play::Scissors, + (Play::Scissors, Outcome::Lose) => Play::Paper, + (Play::Scissors, Outcome::Draw) => Play::Scissors, + (Play::Scissors, Outcome::Win) => Play::Rock, + } + } +} + +#[derive(Clone,Copy)] +enum Outcome { + Lose = 0, + Draw = 3, + Win = 6, +} + +struct Game { + opponent: Play, + play: Play, + outcome: Outcome, +} + +impl Game { + fn outcome(&self) -> Outcome { + match (&self.play, &self.opponent) { + (Play::Rock, Play::Rock) => Outcome::Draw, + (Play::Rock, Play::Paper) => Outcome::Lose, + (Play::Rock, Play::Scissors) => Outcome::Win, + (Play::Paper, Play::Rock) => Outcome::Win, + (Play::Paper, Play::Paper) => Outcome::Draw, + (Play::Paper, Play::Scissors) => Outcome::Lose, + (Play::Scissors, Play::Rock) => Outcome::Lose, + (Play::Scissors, Play::Paper) => Outcome::Win, + (Play::Scissors, Play::Scissors) => Outcome::Draw, + } + } + + fn update(&mut self) { + self.play = self.opponent.strategy(self.outcome); + } + + fn score(&self) -> usize { + self.play as usize + self.outcome() as usize + } +} + +fn read_input<T: AsRef<Path>>(filename: T) -> Result<Vec<Game>> { + let reader = BufReader::new(File::open(filename)?); + + reader.lines().map( + |v| { + let s = v?; + let fields: Vec<_> = s.split(' ').collect(); + let opponent = match *(fields.first().ok_or_else(|| anyhow!("Parse error"))?) { + "A" => Ok(Play::Rock), + "B" => Ok(Play::Paper), + "C" => Ok(Play::Scissors), + _ => Err(anyhow!("Invalid input")), + }?; + let ( play, outcome ) = match *(fields.get(1).ok_or_else(|| anyhow!("Parse error"))?) { + "X" => Ok((Play::Rock, Outcome::Lose)), + "Y" => Ok((Play::Paper, Outcome::Draw)), + "Z" => Ok((Play::Scissors, Outcome::Win)), + _ => Err(anyhow!("Invalid input")), + }?; + Ok(Game { opponent, play, outcome }) + } + ).collect() +} + +fn part1(input: &[Game]) -> Result<usize> { + Ok(input.iter().map(|game| game.score()).sum()) +} + +fn part2(input: &mut [Game]) -> Result<usize> { + Ok(input.iter_mut().map(|game| { + game.update(); + game.score() + }).sum()) +} + +fn main() -> Result<()> { + let ( do_part_1, do_part_2 ) = aoc::do_parts(); + + let filename = args().nth(1).ok_or_else(|| anyhow!("Missing input filename"))?; + let mut input = read_input(filename).context("Could not read input")?; + if do_part_1 { + let solution = part1(&input).context("No solution for part 1")?; + println!("Part1, solution found to be: {}", solution); + } + if do_part_2 { + let solution = part2(&mut input).context("No solution for part 2")?; + println!("Part2, solution found to be: {}", solution); + } + Ok(()) +} |