Skip to content

Commit

Permalink
Day 03 solutiosn using nom
Browse files Browse the repository at this point in the history
  • Loading branch information
Cadiac committed Dec 3, 2024
1 parent 486ed51 commit 75909cc
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 4 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,4 @@ This should start the server at `localhost:8080`.

❄️ [Day 01](aoc-solver/src/y2024/day01.rs)
❄️ [Day 02](aoc-solver/src/y2024/day02.rs)
❄️ [Day 03](aoc-solver/src/y2024/day03.rs)
139 changes: 139 additions & 0 deletions aoc-solver/src/y2024/day03.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
use nom::{
branch::alt,
bytes::complete::tag,
character::complete::{anychar, char, digit1},
combinator::{map, map_res},
multi::many0,
sequence::{delimited, preceded, separated_pair},
IResult,
};

use crate::solution::{AocError, Solution};

#[derive(PartialEq, Debug)]
enum Instruction {
Mul(u32, u32),
Enable,
Disable,
}

fn parse_mul(input: &str) -> IResult<&str, (u32, u32)> {
preceded(
tag("mul"),
delimited(
char('('),
separated_pair(
map_res(digit1, |i: &str| i.parse::<u32>()),
char(','),
map_res(digit1, |i: &str| i.parse::<u32>()),
),
char(')'),
),
)(input)
}

fn parse_other(input: &str) -> IResult<&str, ()> {
let (unhandled, _ignored) = anychar(input)?;
Ok((unhandled, ()))
}

fn parse_instruction(input: &str) -> IResult<&str, Option<Instruction>> {
alt((
map(tag("do()"), |_| Some(Instruction::Enable)),
map(tag("don't()"), |_| Some(Instruction::Disable)),
map(parse_mul, |(a, b)| Some(Instruction::Mul(a, b))),
map(parse_other, |_| None),
))(input)
}

fn parse(input: &str) -> Result<Vec<Instruction>, AocError> {
let (_unhandled, parsed) =
many0(parse_instruction)(input).map_err(|err| AocError::parse(input, err))?;

let instructions = parsed.into_iter().flatten().collect();

Ok(instructions)
}

pub struct Day03;
impl Solution for Day03 {
type A = u32;
type B = u32;

fn default_input(&self) -> &'static str {
include_str!("../../../inputs/2024/day03.txt")
}

fn part_1(&self, input: &str) -> Result<u32, AocError> {
let sum = parse(input)?
.iter()
.map(|instruction| match instruction {
Instruction::Mul(a, b) => a * b,
_ => 0,
})
.sum();

Ok(sum)
}

fn part_2(&self, input: &str) -> Result<u32, AocError> {
let mut enabled = true;
let sum = parse(input)?
.iter()
.map(|instruction| match instruction {
Instruction::Mul(a, b) if enabled => a * b,
Instruction::Enable => {
enabled = true;
0
}
Instruction::Disable => {
enabled = false;
0
}
_ => 0,
})
.sum();

Ok(sum)
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn it_solves_part1_example() {
assert_eq!(
Day03.part_1(
"xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))"
),
Ok(161)
);
}

#[test]
fn it_solves_part2_example() {
assert_eq!(
Day03.part_2(
"xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))"
),
Ok(48)
);
}

#[test]
fn it_parses_input() {
assert_eq!(
parse("xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))"),
Ok(vec![
Instruction::Mul(2, 4),
Instruction::Disable,
Instruction::Mul(5, 5),
Instruction::Mul(11, 8),
Instruction::Enable,
Instruction::Mul(8, 5),
])
);
}
}
8 changes: 4 additions & 4 deletions aoc-solver/src/y2024/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::solution::{Solution, Solver};

pub mod day01;
pub mod day02;
// pub mod day03;
pub mod day03;
// pub mod day04;
// pub mod day05;
// pub mod day06;
Expand All @@ -26,7 +26,7 @@ pub mod day02;
// pub mod day24;
// pub mod day25;

pub const MAX_DAYS: u8 = 2;
pub const MAX_DAYS: u8 = 3;

pub struct Y2024;

Expand All @@ -35,7 +35,7 @@ impl Solver for Y2024 {
match day {
1 => day01::Day01.run(input, 1, 2024),
2 => day02::Day02.run(input, 2, 2024),
// 3 => day03::Day03.run(input, 3, 2024),
3 => day03::Day03.run(input, 3, 2024),
// 4 => day04::Day04.run(input, 4, 2024),
// 5 => day05::Day05.run(input, 5, 2024),
// 6 => day06::Day06.run(input, 6, 2024),
Expand Down Expand Up @@ -77,7 +77,7 @@ impl Solver for Y2024 {
match day {
1 => include_str!("./day01.rs"),
2 => include_str!("./day02.rs"),
// 3 => include_str!("./day03.rs"),
3 => include_str!("./day03.rs"),
// 4 => include_str!("./day04.rs"),
// 5 => include_str!("./day05.rs"),
// 6 => include_str!("./day06.rs"),
Expand Down
1 change: 1 addition & 0 deletions aoc-web/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub fn header(props: &HeaderProps) -> Html {
<>
<NavLink route={Route::Solution { year: 2024, day: 1 }} current={props.route.clone()} text={"1"}/>
<NavLink route={Route::Solution { year: 2024, day: 2 }} current={props.route.clone()} text={"2"}/>
<NavLink route={Route::Solution { year: 2024, day: 3 }} current={props.route.clone()} text={"3"}/>
</>
}
},
Expand Down
Loading

0 comments on commit 75909cc

Please sign in to comment.