Solve Part 2
This commit is contained in:
parent
4908c5699e
commit
f66ac3eccb
90
src/main.rs
90
src/main.rs
@ -2,9 +2,11 @@
|
|||||||
|
|
||||||
const DATA: &'static str = include_str!("input.txt");
|
const DATA: &'static str = include_str!("input.txt");
|
||||||
|
|
||||||
|
// I can use unwrap()/expect() as much as I want here, since for AoC the input data is expected to make sense.
|
||||||
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
#[derive(PartialEq, Eq)]
|
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||||
enum Move
|
enum Move
|
||||||
{
|
{
|
||||||
Rock,
|
Rock,
|
||||||
@ -13,12 +15,11 @@ enum Move
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq)]
|
#[derive(PartialEq, Eq)]
|
||||||
#[repr(i32)]
|
|
||||||
enum Outcome
|
enum Outcome
|
||||||
{
|
{
|
||||||
Loss = 0,
|
Loss,
|
||||||
Draw = 3,
|
Draw,
|
||||||
Win = 6
|
Win
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Outcome
|
impl Outcome
|
||||||
@ -44,7 +45,7 @@ impl Move
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn did_win(&self, other: &Move) -> Outcome
|
pub fn did_win_against(&self, other: &Move) -> Outcome
|
||||||
{
|
{
|
||||||
if self == other { Outcome::Draw }
|
if self == other { Outcome::Draw }
|
||||||
else {
|
else {
|
||||||
@ -66,6 +67,29 @@ impl Move
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn move_for_outcome(&self, outcome: Outcome) -> Move
|
||||||
|
{
|
||||||
|
if outcome == Outcome::Draw { *self }
|
||||||
|
else {
|
||||||
|
match self {
|
||||||
|
Self::Rock => {
|
||||||
|
if outcome == Outcome::Win { Self::Paper }
|
||||||
|
else { Self::Scissors }
|
||||||
|
}
|
||||||
|
|
||||||
|
Self::Paper => {
|
||||||
|
if outcome == Outcome::Win { Self::Scissors }
|
||||||
|
else { Self::Rock }
|
||||||
|
}
|
||||||
|
|
||||||
|
Self::Scissors => {
|
||||||
|
if outcome == Outcome::Win { Self::Rock }
|
||||||
|
else { Self::Paper }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -89,18 +113,38 @@ impl FromStr for Move {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum OutcomeParseFailure
|
||||||
|
{
|
||||||
|
InvalidOutcome,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for Outcome {
|
||||||
|
type Err = OutcomeParseFailure;
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
match s {
|
||||||
|
"X" => Ok(Self::Loss),
|
||||||
|
"Y" => Ok(Self::Draw),
|
||||||
|
"Z" => Ok(Self::Win),
|
||||||
|
_ => Err(OutcomeParseFailure::InvalidOutcome)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn score_for_round(my_move: &Move, other_move: &Move) -> i32
|
fn score_for_round(my_move: &Move, other_move: &Move) -> i32
|
||||||
{
|
{
|
||||||
let mut score = my_move.as_score();
|
let mut score = my_move.as_score();
|
||||||
|
|
||||||
let outcome = my_move.did_win(other_move);
|
let outcome = my_move.did_win_against(other_move);
|
||||||
|
|
||||||
score += outcome.as_score();
|
score += outcome.as_score();
|
||||||
|
|
||||||
score
|
score
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_round_and_get_score(round_str: &str) -> Option<i32>
|
// Calling nth() on an iterator consumes the returned element, that's why I'm calling nth(0) several times
|
||||||
|
|
||||||
|
fn parse_round_and_get_score_part1(round_str: &str) -> Option<i32>
|
||||||
{
|
{
|
||||||
let mut moves = round_str.split(" ");
|
let mut moves = round_str.split(" ");
|
||||||
|
|
||||||
@ -111,16 +155,42 @@ fn parse_round_and_get_score(round_str: &str) -> Option<i32>
|
|||||||
&first_move.parse().expect("Expected a valid move")))
|
&first_move.parse().expect("Expected a valid move")))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_round_and_get_score_part2(round_str: &str) -> Option<i32>
|
||||||
|
{
|
||||||
|
let mut moves = round_str.split(" ");
|
||||||
|
|
||||||
|
let opponent_move_str = moves.nth(0)?; // Opponent's move goes first
|
||||||
|
let expected_outcome_str = moves.nth(0)?; // Expected outcome goes second
|
||||||
|
|
||||||
|
let expected_outcome: Outcome = expected_outcome_str.parse().expect("Expected a valid outcome");
|
||||||
|
let opponent_move: Move = opponent_move_str.parse().expect("Expected a valid move");
|
||||||
|
|
||||||
|
Some(score_for_round(&opponent_move.move_for_outcome(expected_outcome),
|
||||||
|
&opponent_move))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
fn part1()
|
fn part1()
|
||||||
{
|
{
|
||||||
let mut score = 0;
|
let mut score = 0;
|
||||||
for slice in DATA.split("\n")
|
for slice in DATA.split("\n")
|
||||||
{
|
{
|
||||||
score += parse_round_and_get_score(slice).expect("Input data is not correctly structured");
|
score += parse_round_and_get_score_part1(slice).expect("Input data is not correctly structured");
|
||||||
|
}
|
||||||
|
println!("Your total score is {}", score);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2()
|
||||||
|
{
|
||||||
|
let mut score = 0;
|
||||||
|
for slice in DATA.split("\n")
|
||||||
|
{
|
||||||
|
score += parse_round_and_get_score_part2(slice).expect("Input data is not correctly structured");
|
||||||
}
|
}
|
||||||
println!("Your total score is {}", score);
|
println!("Your total score is {}", score);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
part1();
|
//part1();
|
||||||
|
part2();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user