Solution for day 2

This commit is contained in:
Savanni D'Gerinel 2022-12-02 09:10:12 -05:00
parent 0340f23360
commit 434fdba208
3 changed files with 2683 additions and 0 deletions

2500
problems/data/day2a.txt Normal file

File diff suppressed because it is too large Load Diff

180
problems/src/day2.rs Normal file
View File

@ -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");
}
}

View File

@ -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"),
}; };