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
|
mod utils;
use utils::read_input;
fn main() {
let input = read_input();
let turns_both_moves: Vec<_> = input
.lines()
.map(|xs| {
let mut parts = xs.split(' ').take(2).map(Move::parse);
(parts.next().unwrap(), parts.next().unwrap())
})
.collect();
let total_score_p1: usize = turns_both_moves
.iter()
.map(|(them, us)| score(*them, *us))
.sum();
let total_score_p2: usize = turns_both_moves
.into_iter()
.map(|(them, us)| (them, us.to_outcome()))
.map(|(them, outcome)| (them, them.to_get(outcome)))
.map(|(them, us)| score(them, us))
.sum();
println!("Part 1: {}", total_score_p1);
println!("Part 2: {}", total_score_p2);
}
fn score(them: Move, us: Move) -> usize {
let won_val = match (them.beats(us), us.beats(them)) {
(true, false) => 0,
(false, true) => 6,
(false, false) => 3,
(a, b) => unreachable!("they beat us: {}, we beat them: {}", a, b),
};
us.value() + won_val
}
#[derive(Debug, Clone, Copy)]
enum Move {
Rock,
Paper,
Scissors,
}
impl Move {
fn parse(inp: &str) -> Self {
match inp {
"A" => Move::Rock,
"B" => Move::Paper,
"C" => Move::Scissors,
"X" => Move::Rock,
"Y" => Move::Paper,
"Z" => Move::Scissors,
_ => panic!("unrecognised move: {}", inp),
}
}
fn to_outcome(self) -> Outcome {
match self {
Move::Rock => Outcome::Lose,
Move::Paper => Outcome::Draw,
Move::Scissors => Outcome::Win,
}
}
fn beats(self, other: Move) -> bool {
matches!(
(self, other),
(Move::Paper, Move::Rock)
| (Move::Rock, Move::Scissors)
| (Move::Scissors, Move::Paper)
)
}
fn to_get(self, outcome: Outcome) -> Self {
match (self, outcome) {
(_, Outcome::Draw) => self,
(Move::Rock, Outcome::Win) => Move::Paper,
(Move::Paper, Outcome::Win) => Move::Scissors,
(Move::Scissors, Outcome::Win) => Move::Rock,
(Move::Rock, Outcome::Lose) => Move::Scissors,
(Move::Paper, Outcome::Lose) => Move::Rock,
(Move::Scissors, Outcome::Lose) => Move::Paper,
}
}
fn value(self) -> usize {
match self {
Move::Rock => 1,
Move::Paper => 2,
Move::Scissors => 3,
}
}
}
#[derive(Debug, Clone, Copy)]
enum Outcome {
Win,
Draw,
Lose,
}
|