Probably could've made this shorter but I'm pretty proud of the trick I pulled to parse the input.
use std::io::{Read, stdin};
use itertools::Itertools;
use crate::Janken::*;
use crate::GameResult::*;
enum Janken {
Rock = 1,
Paper = 2,
Scissors = 3
}
enum GameResult {
Loss = 0,
Draw = 3,
Win = 6
}
impl Janken {
fn lose(&self) -> Self {
match self {
Rock => Paper,
Paper => Scissors,
Scissors => Rock
}
}
fn win(&self) -> Self {
match self {
Rock => Scissors,
Paper => Rock,
Scissors => Paper
}
}
}
impl From<u8> for Janken {
fn from(c: u8) -> Self {
match c {
65 => Rock,
66 => Paper,
67 => Scissors,
_ => panic!("unexpected byte")
}
}
}
impl GameResult {
fn force_result(&self, opponent: Janken) -> Janken {
match self {
Loss => opponent.win(),
Draw => opponent,
Win => opponent.lose()
}
}
}
impl From<u8> for GameResult {
fn from(c: u8) -> Self {
match c {
88 => Loss,
89 => Draw,
90 => Win,
_ => panic!("unexpected byte"),
}
}
}
fn main() {
println! { "{}",
stdin()
.bytes()
.step_by(2)
.flatten()
.tuples()
.map(|(opponent, result)| {
let opponent: Janken = opponent.into();
let result: GameResult = result.into();
let me = result.force_result(opponent);
result as u32 + me as u32
})
.sum::<u32>()
}
}