Switch day3b to a nom parser
This commit is contained in:
parent
e121e53258
commit
c170aee068
|
@ -15,6 +15,7 @@ dependencies = [
|
|||
name = "aoc-2024"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"nom",
|
||||
"regex",
|
||||
]
|
||||
|
||||
|
@ -24,6 +25,22 @@ version = "2.7.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.11.1"
|
||||
|
|
|
@ -4,4 +4,5 @@ version = "0.1.0"
|
|||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
nom = "7.1.3"
|
||||
regex = "1.11.1"
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
use nom::{
|
||||
branch::alt, bytes::complete::{tag, take_while}, character::{complete::anychar, is_digit}, combinator::eof, multi::{many1, many_till}, Err, Finish, IResult
|
||||
};
|
||||
use regex::Regex;
|
||||
|
||||
const INPUT: &'static str = include_str!("../data/day3.txt");
|
||||
|
@ -17,7 +20,10 @@ struct State {
|
|||
|
||||
impl Default for State {
|
||||
fn default() -> Self {
|
||||
Self{ mult_enabled: true, value: 0 }
|
||||
Self {
|
||||
mult_enabled: true,
|
||||
value: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,7 +31,7 @@ impl Default for State {
|
|||
enum Operation {
|
||||
Do,
|
||||
Dont,
|
||||
Mult(Multiplication)
|
||||
Mult(Multiplication),
|
||||
}
|
||||
|
||||
impl Operation {
|
||||
|
@ -39,7 +45,7 @@ impl Operation {
|
|||
state.mult_enabled = false;
|
||||
state
|
||||
}
|
||||
Operation::Mult(mul) => mul.run(state)
|
||||
Operation::Mult(mul) => mul.run(state),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -61,28 +67,13 @@ impl Multiplication {
|
|||
|
||||
fn parse_input_a(input: &str) -> Vec<Operation> {
|
||||
let re = Regex::new(r"mul\(([0-9]{1,3}),([0-9]{1,3})\)").unwrap();
|
||||
re.captures_iter(input).map(|capture| {
|
||||
re.captures_iter(input)
|
||||
.map(|capture| {
|
||||
let x = capture.get(1).unwrap().as_str().parse::<i32>().unwrap();
|
||||
let y = capture.get(2).unwrap().as_str().parse::<i32>().unwrap();
|
||||
Operation::Mult(Multiplication { x, y })
|
||||
}).collect::<Vec<Operation>>()
|
||||
}
|
||||
|
||||
fn parse_input_b(input: &str) -> Vec<Operation> {
|
||||
let operation_re = Regex::new(r"do\(\)|don't\(\)|mul\(([0-9]{1,3}),([0-9]{1,3})\)").unwrap();
|
||||
|
||||
operation_re.captures_iter(input).map(|capture| {
|
||||
match capture.get(0).unwrap().as_str()[0..4].as_ref() {
|
||||
"do()" => Operation::Do,
|
||||
"don'" => Operation::Dont,
|
||||
"mul(" => {
|
||||
let x = capture.get(1).unwrap().as_str().parse::<i32>().unwrap();
|
||||
let y = capture.get(2).unwrap().as_str().parse::<i32>().unwrap();
|
||||
Operation::Mult(Multiplication{ x, y })
|
||||
}
|
||||
_ => unimplemented!()
|
||||
}
|
||||
}).collect::<Vec<Operation>>()
|
||||
})
|
||||
.collect::<Vec<Operation>>()
|
||||
}
|
||||
|
||||
fn calculate_part(lst: Vec<Operation>) -> i32 {
|
||||
|
@ -95,12 +86,53 @@ fn calculate_part(lst: Vec<Operation>) -> i32 {
|
|||
state.value
|
||||
}
|
||||
|
||||
fn parse_input_b(input: &str) -> Vec<Operation> {
|
||||
match many1(next_operation)(input).finish() {
|
||||
Ok((_, operations)) => operations,
|
||||
v => panic!("something went wrong: {:?}", v),
|
||||
}
|
||||
}
|
||||
|
||||
fn next_operation(input: &str) -> IResult<&str, Operation> {
|
||||
let (rest, (_discard, operation)) = many_till(anychar, match_operation)(input)?;
|
||||
Ok((rest, operation))
|
||||
}
|
||||
|
||||
fn match_operation(input: &str) -> IResult<&str, Operation> {
|
||||
alt((match_do, match_dont, match_mult))(input)
|
||||
}
|
||||
|
||||
fn match_do(input: &str) -> IResult<&str, Operation> {
|
||||
let (rest, _) = tag("do()")(input)?;
|
||||
Ok((rest, Operation::Do))
|
||||
}
|
||||
|
||||
fn match_dont(input: &str) -> IResult<&str, Operation> {
|
||||
let (rest, _) = tag("don't()")(input)?;
|
||||
Ok((rest, Operation::Dont))
|
||||
}
|
||||
|
||||
fn match_mult(input: &str) -> IResult<&str, Operation> {
|
||||
let (rest, _) = tag("mul(")(input)?;
|
||||
let (rest, x) = take_while(|c| is_digit(c as u8))(rest)?;
|
||||
let (rest, _) = tag(",")(rest)?;
|
||||
let (rest, y) = take_while(|c| is_digit(c as u8))(rest)?;
|
||||
let (rest, _) = tag(")")(rest)?;
|
||||
|
||||
Ok((rest, Operation::Mult(Multiplication {
|
||||
x: x.parse::<i32>().unwrap(),
|
||||
y: y.parse::<i32>().unwrap(),
|
||||
})))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
const TEST_INPUT_A: &'static str = "xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))";
|
||||
const TEST_INPUT_B: &'static str = "xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))";
|
||||
const TEST_INPUT_A: &'static str =
|
||||
"xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))";
|
||||
const TEST_INPUT_B: &'static str =
|
||||
"xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))";
|
||||
|
||||
#[test]
|
||||
fn it_solves_parta() {
|
||||
|
|
Loading…
Reference in New Issue