-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path02.rs
129 lines (114 loc) · 2.58 KB
/
02.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
/*
* Day 2: Rock Paper Scissors
* See [https://adventofcode.com/2022/day/2]
*/
#[derive(PartialEq, Clone, Copy)]
enum Rps {
Rock, Paper, Scissors
}
#[derive(PartialEq, Clone, Copy)]
enum PlayResult {
Lose, Draw, Win
}
fn parse_rps(b: u8) -> Rps {
use Rps::*;
match b {
b'A' | b'X' => Rock,
b'B' | b'Y' => Paper,
b'C' | b'Z' => Scissors,
_ => panic!("Unknown character for type")
}
}
fn parse_result(b: u8) -> PlayResult {
use PlayResult::*;
match b {
b'X' => Lose,
b'Y' => Draw,
b'Z' => Win,
_ => panic!("Unknown character for type")
}
}
macro_rules! beat {
($e:expr, $w:expr) => { if $e == $w { Win } else { Lose } };
}
fn play_rps(you: Rps, enemy: Rps) -> PlayResult {
use Rps::*;
use PlayResult::*;
if you == enemy {
Draw
} else {
match you {
Rock => beat!(enemy, Scissors),
Paper => beat!(enemy, Rock),
Scissors => beat!(enemy, Paper)
}
}
}
fn guess_rps(enemy: Rps, pr: PlayResult) -> Rps {
use Rps::*;
use PlayResult::*;
match pr {
Lose => match enemy {
Rock => Scissors,
Paper => Rock,
Scissors => Paper,
},
Draw => enemy,
Win => match enemy {
Rock => Paper,
Paper => Scissors,
Scissors => Rock,
}
}
}
fn pts(you: Rps, pr: PlayResult) -> u32 {
use Rps::*;
use PlayResult::*;
let a = match you {
Rock => 1,
Paper => 2,
Scissors => 3
};
let b = match pr {
Lose => 0,
Draw => 3,
Win => 6
};
a + b
}
pub fn part_1(input: &str) -> Option<u32> {
let mut sum = 0;
for l in input.lines() {
if l.is_empty() { continue; }
let bl = l.as_bytes();
let (abc, xyz) = (bl[0], bl[2]);
let ce = parse_rps(abc);
let cu = parse_rps(xyz);
let pr = play_rps(cu, ce);
sum += pts(cu, pr);
}
Some(sum)
}
pub fn part_2(input: &str) -> Option<u32> {
let mut sum = 0;
for l in input.lines() {
if l.is_empty() { continue; }
let bl = l.as_bytes();
let (abc, xyz) = (bl[0], bl[2]);
let ce = parse_rps(abc);
let cp = parse_result(xyz);
let u = guess_rps(ce, cp);
sum += pts(u, cp);
}
Some(sum)
}
aoc2022::solve!(part_1, part_2);
#[cfg(test)]
mod tests {
use super::*;
use aoc2022::assert_ex;
#[test]
fn test_part_1() { assert_ex!(part_1, 15); }
#[test]
fn test_part_2() { assert_ex!(part_2, 12); }
}