Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::collections::HashMap;
- #[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
- enum Outcome {
- Win,
- Draw,
- Lose,
- }
- #[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
- enum Shape {
- Rock,
- Paper,
- Scissor,
- }
- fn evaluate_play(player: Shape, elf: Shape) -> Outcome {
- let player_outcomes: HashMap<(Shape, Shape), Outcome> = HashMap::from([
- ((Shape::Rock, Shape::Paper), Outcome::Lose),
- ((Shape::Rock, Shape::Scissor), Outcome::Win),
- ((Shape::Paper, Shape::Scissor), Outcome::Lose),
- ((Shape::Paper, Shape::Rock), Outcome::Win),
- ((Shape::Scissor, Shape::Paper), Outcome::Win),
- ((Shape::Scissor, Shape::Rock), Outcome::Lose),
- ]);
- if player == elf {
- Outcome::Draw
- } else {
- player_outcomes
- .get(&(player, elf))
- .expect("Play should be found.")
- .clone()
- }
- }
- fn score_play(
- play: &str,
- player_map: &HashMap<char, Shape>,
- elf_map: &HashMap<char, Shape>,
- shape_values: &HashMap<Shape, u32>,
- outcome_values: &HashMap<Outcome, u32>,
- ) -> u32 {
- let mut split = play.trim().chars();
- let elf = elf_map
- .get(&split.next().unwrap())
- .expect("Should get elf shape")
- .clone();
- split.next();
- let player = player_map
- .get(&split.next().unwrap())
- .expect("Should get player shape")
- .clone();
- let outcome = evaluate_play(player, elf);
- let outcome_score = outcome_values.get(&outcome).unwrap();
- let play_score = shape_values.get(&player).unwrap();
- outcome_score + play_score
- }
- fn score_guide(
- input: &str,
- player_map: &HashMap<char, Shape>,
- elf_map: &HashMap<char, Shape>,
- shape_values: &HashMap<Shape, u32>,
- outcome_values: &HashMap<Outcome, u32>,
- ) -> u32 {
- input
- .lines()
- .map(|l| score_play(l, player_map, elf_map, shape_values, outcome_values))
- .sum()
- }
- pub fn part_one(input: &str) -> Option<u32> {
- let elf_map: HashMap<char, Shape> = HashMap::from([
- ('A', Shape::Rock),
- ('B', Shape::Paper),
- ('C', Shape::Scissor),
- ]);
- let player_map: HashMap<char, Shape> = HashMap::from([
- ('X', Shape::Rock),
- ('Y', Shape::Paper),
- ('Z', Shape::Scissor),
- ]);
- let shape_values: HashMap<Shape, u32> = HashMap::from([
- (Shape::Rock, 1),
- (Shape::Paper, 2),
- (Shape::Scissor, 3),
- ]);
- let outcome_values: HashMap<Outcome, u32> = HashMap::from([
- (Outcome::Win, 6),
- (Outcome::Draw, 3),
- (Outcome::Lose, 0),
- ]);
- Some(score_guide(input, &player_map, &elf_map, &shape_values, &outcome_values))
- }
- pub fn part_two(input: &str) -> Option<u32> {
- let mut score: u32 = 0;
- let elf_map: HashMap<char, Shape> = HashMap::from([
- ('A', Shape::Rock),
- ('B', Shape::Paper),
- ('C', Shape::Scissor),
- ]);
- let outcome_map: HashMap<char, Outcome> = HashMap::from([
- ('X', Outcome::Lose),
- ('Y', Outcome::Draw),
- ('Z', Outcome::Win),
- ]);
- let shape_values: HashMap<Shape, u32> = HashMap::from([
- (Shape::Rock, 1),
- (Shape::Paper, 2),
- (Shape::Scissor, 3),
- ]);
- for line in input.lines() {
- let mut split = line.trim().chars();
- let elf = elf_map
- .get(&split.next().unwrap())
- .expect("Should get elf shape")
- .clone();
- split.next();
- let outcome = outcome_map
- .get(&split.next().unwrap())
- .expect("Should get player outcome")
- .clone();
- if outcome == Outcome::Draw {
- score += 3;
- score += shape_values.get(&elf).unwrap();
- } else if outcome == Outcome::Win {
- match elf {
- Shape::Paper => {
- score += 9;
- },
- Shape::Scissor => {
- score += 7;
- }
- Shape::Rock => {
- score += 8;
- }
- }
- } else {
- match elf {
- Shape::Paper => {
- score += 1;
- },
- Shape::Scissor => {
- score += 2;
- }
- Shape::Rock => {
- score += 3;
- }
- }
- }
- }
- Some(score)
- }
Advertisement
Add Comment
Please, Sign In to add comment