summaryrefslogtreecommitdiffstats
path: root/day02a/src
diff options
context:
space:
mode:
Diffstat (limited to 'day02a/src')
-rw-r--r--day02a/src/main.rs167
1 files changed, 166 insertions, 1 deletions
diff --git a/day02a/src/main.rs b/day02a/src/main.rs
index e7a11a9..56c7378 100644
--- a/day02a/src/main.rs
+++ b/day02a/src/main.rs
@@ -1,3 +1,168 @@
+/// --- Day 2: Rock Paper Scissors ---
+///
+/// The Elves begin to set up camp on the beach. To decide whose tent gets to be closest to the
+/// snack storage, a giant Rock Paper Scissors tournament is already in progress.
+///
+/// Rock Paper Scissors is a game between two players. Each game contains many rounds; in each
+/// round, the players each simultaneously choose one of Rock, Paper, or Scissors using a hand
+/// shape. Then, a winner for that round is selected: Rock defeats Scissors, Scissors defeats
+/// Paper, and Paper defeats Rock. If both players choose the same shape, the round instead ends
+/// in a draw.
+///
+/// Appreciative of your help yesterday, one Elf gives you an encrypted strategy guide (your puzzle
+/// input) that they say will be sure to help you win. "The first column is what your opponent is
+/// going to play: A for Rock, B for Paper, and C for Scissors. The second column--" Suddenly, the
+/// Elf is called away to help with someone's tent.
+///
+/// The second column, you reason, must be what you should play in response: X for Rock, Y for
+/// Paper, and Z for Scissors. Winning every time would be suspicious, so the responses must have
+/// been carefully chosen.
+///
+/// The winner of the whole tournament is the player with the highest score. Your total score is
+/// the sum of your scores for each round. The score for a single round is the score for the shape
+/// you selected (1 for Rock, 2 for Paper, and 3 for Scissors) plus the score for the outcome of
+/// the round (0 if you lost, 3 if the round was a draw, and 6 if you won).
+///
+/// Since you can't be sure if the Elf is trying to help you or trick you, you should calculate the
+/// score you would get if you were to follow the strategy guide.
+///
+/// For example, suppose you were given the following strategy guide:
+///
+/// ```
+/// A Y
+/// B X
+/// C Z
+/// ```
+///
+/// This strategy guide predicts and recommends the following:
+///
+/// In the first round, your opponent will choose Rock (A), and you should choose Paper (Y).
+/// This ends in a win for you with a score of 8 (2 because you chose Paper + 6 because you
+/// won).
+/// In the second round, your opponent will choose Paper (B), and you should choose Rock (X).
+/// This ends in a loss for you with a score of 1 (1 + 0).
+/// The third round is a draw with both players choosing Scissors, giving you a score of 3 + 3
+/// = 6.
+///
+/// In this example, if you were to follow the strategy guide, you would get a total score of 15 (8
+/// + 1 + 6).
+///
+/// What would your total score be if everything goes exactly according to your strategy guide?
+use clap::Parser;
+use itertools::Itertools;
+
+use std::fs::File;
+use std::io::prelude::*;
+use std::io::BufReader;
+use std::path::PathBuf;
+
+const FILEPATH: &'static str = "examples/input.txt";
+
+#[derive(Parser, Debug)]
+#[clap(author, version, about, long_about = None)]
+struct Cli {
+ #[clap(short, long, default_value = FILEPATH)]
+ file: PathBuf,
+}
+
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
+enum RockPaperScissorsKind {
+ Rock,
+ Paper,
+ Scissors,
+}
+
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
+enum GameOutcome {
+ Win,
+ Loss,
+ Draw,
+}
+
+#[derive(Copy, Clone, Debug)]
+struct GamePrediction {
+ player: RockPaperScissorsKind,
+ opponent: RockPaperScissorsKind,
+}
+
+fn kind_to_value(kind: RockPaperScissorsKind) -> i32 {
+ use RockPaperScissorsKind::*;
+ match kind {
+ Rock => 1,
+ Paper => 2,
+ Scissors => 3,
+ }
+}
+
+fn opp_to_kind(val: char) -> Option<RockPaperScissorsKind> {
+ use RockPaperScissorsKind::*;
+ match val {
+ 'A' => Some(Rock),
+ 'B' => Some(Paper),
+ 'C' => Some(Scissors),
+ _ => None,
+ }
+}
+
+fn player_to_kind(val: char) -> Option<RockPaperScissorsKind> {
+ use RockPaperScissorsKind::*;
+ match val {
+ 'X' => Some(Rock),
+ 'Y' => Some(Paper),
+ 'Z' => Some(Scissors),
+ _ => None,
+ }
+}
+
+fn outcome_to_value(outcome: GameOutcome) -> i32 {
+ use GameOutcome::*;
+ match outcome {
+ Win => 6,
+ Draw => 3,
+ Loss => 0,
+ }
+}
+
+fn game_pred_to_outcome(prediction: GamePrediction) -> GameOutcome {
+ use GameOutcome::*;
+ use RockPaperScissorsKind::*;
+ match (prediction.player, prediction.opponent) {
+ (Rock, Scissors) => Win,
+ (Scissors, Paper) => Win,
+ (Paper, Rock) => Win,
+ (x, y) if x == y => Draw,
+ _ => Loss,
+ }
+}
+
+fn game_pred_to_value(prediction: GamePrediction) -> i32 {
+ outcome_to_value(game_pred_to_outcome(prediction)) + kind_to_value(prediction.player)
+}
+
fn main() {
- println!("Hello, world!");
+ let args = Cli::parse();
+
+ let file = File::open(&args.file).unwrap();
+ let reader = BufReader::new(file);
+ let res: i32 = reader
+ .lines()
+ .map(|l| {
+ l.unwrap()
+ .split(' ')
+ .map(|w| w.parse::<char>().unwrap())
+ .collect_tuple::<(char, char)>()
+ })
+ .map(|v| v.unwrap())
+ .map(|(o_char, p_char)| GamePrediction {
+ player: player_to_kind(p_char).unwrap(),
+ opponent: opp_to_kind(o_char).unwrap(),
+ })
+ .map(|pred| game_pred_to_value(pred))
+ // .inspect(|x| println!("{x:?}"))
+ .sum();
+
+ println!(
+ "The total score if everything goes exactly according to your strategy guide is {}",
+ res
+ );
}