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 day1;
|
||||||
|
mod day2;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let day = std::env::args().skip(1).next();
|
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()) {
|
let result = match day.as_ref().map(|v| v.as_ref()) {
|
||||||
Some("1a") => day1::part1(),
|
Some("1a") => day1::part1(),
|
||||||
Some("1b") => day1::part2(),
|
Some("1b") => day1::part2(),
|
||||||
|
Some("2a") => day2::part1(),
|
||||||
|
Some("2b") => day2::part2(),
|
||||||
_ => panic!("unrecognized day"),
|
_ => panic!("unrecognized day"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue