[rs] Solve 2022_02 part 2

This commit is contained in:
Joscha 2022-12-02 13:31:02 +01:00
parent 1a8b4df940
commit daa1ee9183

View file

@ -6,22 +6,54 @@ enum Choice {
} }
impl Choice { impl Choice {
fn score_against(self, other: Self) -> u32 { fn score(self) -> u32 {
use self::Choice::*; match self {
Self::Rock => 1,
Self::Paper => 2,
Self::Scissors => 3,
}
}
(match self { fn against(self, opponent: Self) -> Outcome {
Rock => 1, use self::Choice::*;
Paper => 2, match (self, opponent) {
Scissors => 3, (Rock, Paper) | (Paper, Scissors) | (Scissors, Rock) => Outcome::Lose,
} + match (self, other) { (Rock, Rock) | (Paper, Paper) | (Scissors, Scissors) => Outcome::Draw,
(Rock, Paper) | (Paper, Scissors) | (Scissors, Rock) => 0, (Rock, Scissors) | (Paper, Rock) | (Scissors, Paper) => Outcome::Win,
(Rock, Rock) | (Paper, Paper) | (Scissors, Scissors) => 3, }
(Rock, Scissors) | (Paper, Rock) | (Scissors, Paper) => 6,
})
} }
} }
fn read_round(line: &str) -> (Choice, Choice) { #[derive(Clone, Copy, PartialEq, Eq)]
enum Outcome {
Lose,
Draw,
Win,
}
impl Outcome {
fn score(self) -> u32 {
match self {
Outcome::Lose => 0,
Outcome::Draw => 3,
Outcome::Win => 6,
}
}
fn against(self, opponent: Choice) -> Choice {
match (self, opponent) {
(Self::Lose, Choice::Rock) => Choice::Scissors,
(Self::Lose, Choice::Paper) => Choice::Rock,
(Self::Lose, Choice::Scissors) => Choice::Paper,
(Self::Draw, c) => c,
(Self::Win, Choice::Rock) => Choice::Paper,
(Self::Win, Choice::Paper) => Choice::Scissors,
(Self::Win, Choice::Scissors) => Choice::Rock,
}
}
}
fn read_round(line: &str) -> (Choice, Choice, Outcome) {
let elems = line.split(' ').take(2).collect::<Vec<_>>(); let elems = line.split(' ').take(2).collect::<Vec<_>>();
let l = match elems[0] { let l = match elems[0] {
"A" => Choice::Rock, "A" => Choice::Rock,
@ -29,27 +61,34 @@ fn read_round(line: &str) -> (Choice, Choice) {
"C" => Choice::Scissors, "C" => Choice::Scissors,
_ => panic!(), _ => panic!(),
}; };
let r = match elems[1] { let (rc, ro) = match elems[1] {
"X" => Choice::Rock, "X" => (Choice::Rock, Outcome::Lose),
"Y" => Choice::Paper, "Y" => (Choice::Paper, Outcome::Draw),
"Z" => Choice::Scissors, "Z" => (Choice::Scissors, Outcome::Win),
_ => panic!(), _ => panic!(),
}; };
(l, r) (l, rc, ro)
} }
pub fn solve(input: String) -> anyhow::Result<()> { pub fn solve(input: String) -> anyhow::Result<()> {
let choices = input let matches = input
.lines() .lines()
.map(|l| read_round(l.trim())) .map(|l| read_round(l.trim()))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
// Part 1 // Part 1
let score = choices let score = matches
.iter() .iter()
.map(|(l, r)| r.score_against(*l)) .map(|(l, r, _)| r.score() + r.against(*l).score())
.sum::<u32>(); .sum::<u32>();
println!("Part 1: {score}"); println!("Part 1: {score}");
// Part 2
let score = matches
.iter()
.map(|(l, _, r)| r.against(*l).score() + r.score())
.sum::<u32>();
println!("Part 2: {score}");
Ok(()) Ok(())
} }