-
Notifications
You must be signed in to change notification settings - Fork 0
/
part_two.rs
130 lines (113 loc) Β· 3.69 KB
/
part_two.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
use std::error::Error;
// Enum that describes match result.
enum Outcome {
Win,
Draw,
Lose,
}
// Trait for outcome to calculate result score.
impl Outcome {
pub fn get_score(&self) -> u32 {
match &self {
Outcome::Win => 6,
Outcome::Draw => 3,
Outcome::Lose => 0,
}
}
}
// Possible Items that players can throw.
#[derive(Clone)]
enum Item {
Rock,
Paper,
Scissors,
}
impl Item {
// Value of each Item.
pub fn get_score(&self) -> u32 {
match &self {
Item::Rock => 1,
Item::Paper => 2,
Item::Scissors => 3,
}
}
// Returns an Item that we must use to get desired outcome using current Item.
pub fn get_item_from_outcome(&self, outcome: &Outcome) -> Self {
match (&self, &outcome) {
(Item::Rock, Outcome::Win) => Item::Paper,
(Item::Rock, Outcome::Lose) => Item::Scissors,
(Item::Paper, Outcome::Win) => Item::Scissors,
(Item::Paper, Outcome::Lose) => Item::Rock,
(Item::Scissors, Outcome::Win) => Item::Rock,
(Item::Scissors, Outcome::Lose) => Item::Paper,
(_, Outcome::Draw) => self.clone(),
}
}
}
// Struct that holds each game Round.
struct Round {
opponent: Item,
player: Item,
}
impl Round {
// Common Rust way to create structs.
pub fn new(opponent: Item, player: Item) -> Self {
Self { opponent, player }
}
// Calculate outcome of the Round.
pub fn get_outcome(&self) -> Outcome {
match (&self.player, &self.opponent) {
(Item::Rock, Item::Scissors) => Outcome::Win,
(Item::Rock, Item::Paper) => Outcome::Lose,
(Item::Paper, Item::Rock) => Outcome::Win,
(Item::Paper, Item::Scissors) => Outcome::Lose,
(Item::Scissors, Item::Paper) => Outcome::Win,
(Item::Scissors, Item::Rock) => Outcome::Lose,
_ => Outcome::Draw,
}
}
// Calculate score of the round.
pub fn calc_score(&self) -> u32 {
&self.player.get_score() + &self.get_outcome().get_score()
}
}
// Program entry point.
fn main() -> Result<(), Box<dyn Error>> {
// List of game rounds.
let mut rounds: Vec<Round> = Vec::new();
// Read input file into String.
let file = std::fs::read_to_string("../input.txt")?;
// For each line in the file.
for line in file.lines() {
// Split a line in two values.
let mut iter = line.split_whitespace();
// First value is what current opponent is throwing.
let current_opponent = match iter.next() {
Some(v) => match v {
"A" => Item::Rock,
"B" => Item::Paper,
"C" => Item::Scissors,
_ => todo!(),
},
None => todo!(),
};
// Second value is what outcome we must get.
let current_outcome = match iter.next() {
Some(v) => match v {
"X" => Outcome::Lose,
"Y" => Outcome::Draw,
"Z" => Outcome::Win,
_ => todo!(),
},
None => todo!(),
};
// Get player item with the outcome we need to fulfill.
let current_player = current_opponent.get_item_from_outcome(¤t_outcome);
// Create a new Round struct with opponent and player values.
rounds.push(Round::new(current_opponent, current_player));
}
// Calculate a final sum by calling a score calculation method of Round struct and summing those up.
let final_sum: u32 = rounds.into_iter().map(|r| r.calc_score()).sum();
println!("Final Score: {final_sum}");
Ok(())
}