summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcos <cos>2022-12-04 17:32:57 +0000
committercos <cos>2022-12-05 11:14:34 +0000
commit002f3d163bd606434d5e73e1658caad29690f03b (patch)
treebed020ea4991845b5b59b2179a6b17c3d7328c3b
parent5886b1144dac92767b49028bd0d7093667fdafb3 (diff)
downloadadventofcode-002f3d163bd606434d5e73e1658caad29690f03b.zip
Add day02, 2022
-rw-r--r--2022/rust/Cargo.toml2
-rw-r--r--2022/rust/day02/Cargo.toml8
-rw-r--r--2022/rust/day02/src/main.rs127
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(())
+}