day3, part2

This commit is contained in:
Joe Ardent 2024-12-21 18:00:11 -08:00
parent 7c962a202b
commit 6c894246f4

View file

@ -8,24 +8,65 @@ use winnow::{
fn main() { fn main() {
let input = std::fs::read_to_string("input").unwrap(); let input = std::fs::read_to_string("input").unwrap();
println!("{}", pt1(&input)); println!("{}", pt1(&input));
println!("{}", pt2(&input));
} }
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
enum Inst { enum Inst {
Mul(i32, i32), Mul(i64, i64),
Do,
Dont,
} }
fn pt1(input: &str) -> i32 { fn pt1(input: &str) -> i64 {
let mut input = input; let mut input = input;
let v = parse(&mut input).unwrap(); let v = parse(&mut input).unwrap();
v.iter().map(|Inst::Mul(a, b)| (a * b)).sum() v.iter()
.map(|inst| match inst {
Inst::Mul(a, b) => a * b,
_ => 0,
})
.sum()
}
fn pt2(input: &str) -> i64 {
let mut input = input;
let instructions = parse(&mut input).unwrap();
let mut doo = true;
let mut total = 0;
for i in &instructions {
match i {
Inst::Do => doo = true,
Inst::Dont => doo = false,
Inst::Mul(a, b) => {
if doo {
total += a * b;
}
}
}
}
total
}
fn parse_mul(input: &mut &str) -> PResult<Inst> {
let _ = "mul".parse_next(input)?;
let pair: (i64, i64) =
delimited('(', separated_pair(dec_int, ',', dec_int), ')').parse_next(input)?;
Ok(Inst::Mul(pair.0, pair.1))
}
fn parse_do(input: &mut &str) -> PResult<Inst> {
let _ = "do()".parse_next(input)?;
Ok(Inst::Do)
}
fn parse_dont(input: &mut &str) -> PResult<Inst> {
let _ = "don't()".parse_next(input)?;
Ok(Inst::Dont)
} }
fn parse_inst(input: &mut &str) -> PResult<Inst> { fn parse_inst(input: &mut &str) -> PResult<Inst> {
let _ = "mul".parse_next(input)?; alt((parse_mul, parse_do, parse_dont)).parse_next(input)
let pair: (i32, i32) =
delimited('(', separated_pair(dec_int, ',', dec_int), ')').parse_next(input)?;
Ok(Inst::Mul(pair.0, pair.1))
} }
fn parse(input: &mut &str) -> PResult<Vec<Inst>> { fn parse(input: &mut &str) -> PResult<Vec<Inst>> {
@ -50,11 +91,18 @@ fn parse(input: &mut &str) -> PResult<Vec<Inst>> {
mod test { mod test {
use super::*; use super::*;
static INPUT: &str = "xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))"; static INPUT1: &str = "xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))";
static INPUT2: &str =
"xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))";
#[test] #[test]
fn p1() { fn p1() {
let v = pt1(INPUT); let v = pt1(INPUT1);
assert_eq!(v, 161) assert_eq!(v, 161)
} }
#[test]
fn p2() {
assert_eq!(48, pt2(INPUT2));
}
} }