aboutsummaryrefslogtreecommitdiff
path: root/2022/src/day02.rs
diff options
context:
space:
mode:
authorAria <me@aria.rip>2023-01-02 21:58:56 +0000
committerAria <me@aria.rip>2023-01-02 21:58:56 +0000
commit5eb58ad076f2cd435b11b140820da224b60b73d5 (patch)
tree2a67939595fbf993ff04f69b9cd3f0aa20827d96 /2022/src/day02.rs
initial commit
Diffstat (limited to '2022/src/day02.rs')
-rw-r--r--2022/src/day02.rs105
1 files changed, 105 insertions, 0 deletions
diff --git a/2022/src/day02.rs b/2022/src/day02.rs
new file mode 100644
index 0000000..d0b0c5f
--- /dev/null
+++ b/2022/src/day02.rs
@@ -0,0 +1,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,
+}