Solution for day 2
This commit is contained in:
parent
0340f23360
commit
434fdba208
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,180 @@
|
|||
const PART2: &str = include_str!("../data/day2a.txt");
|
||||
|
||||
pub fn part1() -> String {
|
||||
format!("{}", score_match(input(PART2)))
|
||||
}
|
||||
|
||||
pub fn part2() -> String {
|
||||
let result = input_b(PART2)
|
||||
.into_iter()
|
||||
.map(|(other, needed)| score((other, needed.choose(other))))
|
||||
.fold(0, |a, b| a + b);
|
||||
|
||||
format!("{}", result)
|
||||
}
|
||||
|
||||
fn input(data: &str) -> Vec<(RPS, RPS)> {
|
||||
data.lines().map(parse_line_a).collect::<Vec<(RPS, RPS)>>()
|
||||
}
|
||||
|
||||
fn input_b(data: &str) -> Vec<(RPS, NeededResult)> {
|
||||
data.lines()
|
||||
.map(parse_line_b)
|
||||
.collect::<Vec<(RPS, NeededResult)>>()
|
||||
}
|
||||
|
||||
fn score_match(shots: Vec<(RPS, RPS)>) -> u32 {
|
||||
shots.into_iter().map(score).fold(0, |a, b| a + b)
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
enum RPS {
|
||||
Rock,
|
||||
Paper,
|
||||
Scissors,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
enum Winner {
|
||||
Other,
|
||||
Me,
|
||||
Tie,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
enum NeededResult {
|
||||
Win,
|
||||
Lose,
|
||||
Draw,
|
||||
}
|
||||
|
||||
impl NeededResult {
|
||||
fn choose(self, source: RPS) -> RPS {
|
||||
match (self, source) {
|
||||
(Self::Win, RPS::Rock) => RPS::Paper,
|
||||
(Self::Win, RPS::Paper) => RPS::Scissors,
|
||||
(Self::Win, RPS::Scissors) => RPS::Rock,
|
||||
|
||||
(Self::Lose, RPS::Rock) => RPS::Scissors,
|
||||
(Self::Lose, RPS::Paper) => RPS::Rock,
|
||||
(Self::Lose, RPS::Scissors) => RPS::Paper,
|
||||
|
||||
(Self::Draw, _) => source,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for NeededResult {
|
||||
fn from(val: &str) -> Self {
|
||||
match val {
|
||||
"X" => NeededResult::Lose,
|
||||
"Y" => NeededResult::Draw,
|
||||
"Z" => NeededResult::Win,
|
||||
_ => panic!("unknown"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn round_result(lside: RPS, rside: RPS) -> Winner {
|
||||
match (lside, rside) {
|
||||
(RPS::Rock, RPS::Rock) => Winner::Tie,
|
||||
(RPS::Rock, RPS::Paper) => Winner::Me,
|
||||
(RPS::Rock, RPS::Scissors) => Winner::Other,
|
||||
|
||||
(RPS::Paper, RPS::Paper) => Winner::Tie,
|
||||
(RPS::Paper, RPS::Rock) => Winner::Other,
|
||||
(RPS::Paper, RPS::Scissors) => Winner::Me,
|
||||
|
||||
(RPS::Scissors, RPS::Scissors) => Winner::Tie,
|
||||
(RPS::Scissors, RPS::Rock) => Winner::Me,
|
||||
(RPS::Scissors, RPS::Paper) => Winner::Other,
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for RPS {
|
||||
fn from(val: &str) -> RPS {
|
||||
match val {
|
||||
"A" | "X" => RPS::Rock,
|
||||
"B" | "Y" => RPS::Paper,
|
||||
"C" | "Z" => RPS::Scissors,
|
||||
_ => panic!("unknown"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_line_a(line: &str) -> (RPS, RPS) {
|
||||
let vals = line.split(" ").map(RPS::from).take(2).collect::<Vec<RPS>>();
|
||||
(vals[0].clone(), vals[1].clone())
|
||||
}
|
||||
|
||||
fn parse_line_b(line: &str) -> (RPS, NeededResult) {
|
||||
let vals = line.split(" ").collect::<Vec<&str>>();
|
||||
(RPS::from(vals[0]), NeededResult::from(vals[1]))
|
||||
}
|
||||
|
||||
fn score(shot: (RPS, RPS)) -> u32 {
|
||||
let result_score = match round_result(shot.0, shot.1) {
|
||||
Winner::Other => 0,
|
||||
Winner::Me => 6,
|
||||
Winner::Tie => 3,
|
||||
};
|
||||
|
||||
let choice = match shot.1 {
|
||||
RPS::Rock => 1,
|
||||
RPS::Paper => 2,
|
||||
RPS::Scissors => 3,
|
||||
};
|
||||
|
||||
choice + result_score
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
const EXAMPLE: &str = "A Y
|
||||
B X
|
||||
C Z";
|
||||
|
||||
#[test]
|
||||
fn it_scores_a_round() {
|
||||
assert_eq!(score(parse_line_a("A Y")), 8);
|
||||
assert_eq!(score(parse_line_a("B X")), 1);
|
||||
assert_eq!(score(parse_line_a("C Z")), 6);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_scores_a_match() {
|
||||
assert_eq!(score_match(input(EXAMPLE)), 15);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_makes_right_choice() {
|
||||
{
|
||||
let (source, needed) = parse_line_b("A Y");
|
||||
let me = needed.choose(source);
|
||||
assert_eq!(score((source, me)), 4);
|
||||
}
|
||||
{
|
||||
let (source, needed) = parse_line_b("B X");
|
||||
let me = needed.choose(source);
|
||||
println!("{:?}, {:?}, {:?}", source, needed, me);
|
||||
assert_eq!(score((source, me)), 1);
|
||||
}
|
||||
{
|
||||
let (source, needed) = parse_line_b("C Z");
|
||||
let me = needed.choose(source);
|
||||
assert_eq!(score((source, me)), 7);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_runs_part1() {
|
||||
assert_eq!(part1(), "15523");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_runs_part2() {
|
||||
assert_eq!(part2(), "15702");
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
mod day1;
|
||||
mod day2;
|
||||
|
||||
fn main() {
|
||||
let day = std::env::args().skip(1).next();
|
||||
|
@ -6,6 +7,8 @@ fn main() {
|
|||
let result = match day.as_ref().map(|v| v.as_ref()) {
|
||||
Some("1a") => day1::part1(),
|
||||
Some("1b") => day1::part2(),
|
||||
Some("2a") => day2::part1(),
|
||||
Some("2b") => day2::part2(),
|
||||
_ => panic!("unrecognized day"),
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue