122 lines
2.8 KiB
Rust
122 lines
2.8 KiB
Rust
|
use std::{
|
||
|
io::{stdin, Read},
|
||
|
str::FromStr,
|
||
|
};
|
||
|
|
||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||
|
enum Rps {
|
||
|
Rock,
|
||
|
Paper,
|
||
|
Scissors,
|
||
|
}
|
||
|
|
||
|
impl Rps {
|
||
|
fn outcome_against(&self, other: Rps) -> Outcome {
|
||
|
match (self, other) {
|
||
|
(Rps::Rock, Rps::Scissors) | (Rps::Paper, Rps::Rock) | (Rps::Scissors, Rps::Paper) => {
|
||
|
Outcome::Win
|
||
|
}
|
||
|
(Rps::Rock, Rps::Rock) | (Rps::Paper, Rps::Paper) | (Rps::Scissors, Rps::Scissors) => {
|
||
|
Outcome::Draw
|
||
|
}
|
||
|
(Rps::Rock, Rps::Paper) | (Rps::Paper, Rps::Scissors) | (Rps::Scissors, Rps::Rock) => {
|
||
|
Outcome::Lose
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn score(&self) -> u64 {
|
||
|
match self {
|
||
|
Rps::Rock => 1,
|
||
|
Rps::Paper => 2,
|
||
|
Rps::Scissors => 3,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn with_outcome(&self, outcome: Outcome) -> Rps {
|
||
|
match (self, outcome) {
|
||
|
(r, Outcome::Draw) => *r,
|
||
|
|
||
|
(Rps::Rock, Outcome::Lose) => Rps::Scissors,
|
||
|
(Rps::Paper, Outcome::Lose) => Rps::Rock,
|
||
|
(Rps::Scissors, Outcome::Lose) => Rps::Paper,
|
||
|
|
||
|
(Rps::Rock, Outcome::Win) => Rps::Paper,
|
||
|
(Rps::Paper, Outcome::Win) => Rps::Scissors,
|
||
|
(Rps::Scissors, Outcome::Win) => Rps::Rock,
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl FromStr for Rps {
|
||
|
type Err = ();
|
||
|
|
||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||
|
match s {
|
||
|
"A" | "X" => Ok(Rps::Rock),
|
||
|
"B" | "Y" => Ok(Rps::Paper),
|
||
|
"C" | "Z" => Ok(Rps::Scissors),
|
||
|
_ => Err(()),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||
|
enum Outcome {
|
||
|
Lose,
|
||
|
Draw,
|
||
|
Win,
|
||
|
}
|
||
|
|
||
|
impl Outcome {
|
||
|
fn score(&self) -> u64 {
|
||
|
match self {
|
||
|
Outcome::Lose => 0,
|
||
|
Outcome::Draw => 3,
|
||
|
Outcome::Win => 6,
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl FromStr for Outcome {
|
||
|
type Err = ();
|
||
|
|
||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||
|
match s {
|
||
|
"X" => Ok(Outcome::Lose),
|
||
|
"Y" => Ok(Outcome::Draw),
|
||
|
"Z" => Ok(Outcome::Win),
|
||
|
_ => Err(()),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn main() {
|
||
|
let mut data = String::new();
|
||
|
stdin().read_to_string(&mut data).unwrap();
|
||
|
|
||
|
let mut sum1 = 0u64;
|
||
|
let mut sum2 = 0u64;
|
||
|
|
||
|
for line in data.lines() {
|
||
|
let parts: Vec<_> = line.split_whitespace().collect();
|
||
|
let other: Rps = parts[0].parse().unwrap();
|
||
|
|
||
|
{
|
||
|
let me: Rps = parts[1].parse().unwrap();
|
||
|
let outcome = me.outcome_against(other);
|
||
|
|
||
|
sum1 += me.score() + outcome.score();
|
||
|
}
|
||
|
{
|
||
|
let outcome = parts[1].parse().unwrap();
|
||
|
let me = other.with_outcome(outcome);
|
||
|
|
||
|
sum2 += me.score() + outcome.score();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
println!("{}", sum1);
|
||
|
println!("{}", sum2);
|
||
|
}
|