From d56154f5c241bba7ef16d27cbf8bb1e7e4f23517 Mon Sep 17 00:00:00 2001 From: Matej Focko Date: Sun, 11 Dec 2022 14:23:02 +0100 Subject: [PATCH] day(11): refactor parsing Signed-off-by: Matej Focko --- src/bin/day11.rs | 62 ++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 34 deletions(-) diff --git a/src/bin/day11.rs b/src/bin/day11.rs index 46c5f03..b30a770 100644 --- a/src/bin/day11.rs +++ b/src/bin/day11.rs @@ -4,6 +4,8 @@ use aoc_2022::*; use color_eyre::{eyre::eyre, Report}; use itertools::Itertools; +use lazy_static::lazy_static; +use regex::Regex; use tracing::debug; type Input = Vec; @@ -32,14 +34,13 @@ impl FromStr for Operation { type Err = Report; fn from_str(s: &str) -> Result { - let (_, rhs) = s - .split(" = ") - .collect_tuple() - .ok_or(eyre!("couldn't split operation"))?; - let (l, op, r) = rhs - .split_ascii_whitespace() - .collect_tuple() - .ok_or(eyre!("couldn't split the expression"))?; + lazy_static! { + static ref OPERATION_REGEX: Regex = + Regex::new(r"(?P.*) (?P\+|\*) (?P.*)").unwrap(); + } + + let caps = OPERATION_REGEX.captures(s).unwrap(); + let (l, op, r) = (&caps["l"], &caps["op"], &caps["r"]); if l == r { match op { @@ -59,7 +60,6 @@ impl FromStr for Operation { #[derive(Clone)] struct Test(usize, usize, usize); - impl Test { fn get(&self, worry: usize) -> usize { let &Test(div, t, f) = self; @@ -72,21 +72,6 @@ impl Test { } } -impl FromStr for Test { - type Err = Report; - - fn from_str(s: &str) -> Result { - let (divisor, t_branch, f_branch) = s - .split('\n') - .map(|l| l.split_ascii_whitespace().last().unwrap()) - .map(|n| n.parse().unwrap()) - .collect_tuple() - .ok_or(eyre!("couldn't parse the test"))?; - - Ok(Test(divisor, t_branch, f_branch)) - } -} - #[derive(Clone)] struct Monkey { items: Vec, @@ -100,20 +85,29 @@ impl FromStr for Monkey { type Err = Report; fn from_str(s: &str) -> Result { - let (_, items_s, op_s, test_s, t_s, f_s) = s - .split('\n') - .collect_tuple() - .ok_or(eyre!("Couldn't split string correctly"))?; + lazy_static! { + static ref MONKEY_REGEX: Regex = Regex::new(concat!( + r"(?s)", + r"Starting items: (?P[^\n]+).*", + r"Operation: new = (?P[^\n]*).*", + r"Test: divisible by (?P
\d+).*", + r"If true: throw to monkey (?P\d+).*", + r"If false: throw to monkey (?P\d+)", + )) + .unwrap(); + } - let items = items_s - .split(": ") - .nth(1) - .ok_or(eyre!("No items present"))? + let caps = MONKEY_REGEX.captures(s).unwrap(); + let items = caps["items"] .split(", ") .map(|x| x.parse().unwrap()) .collect_vec(); - let operation = op_s.parse()?; - let test = vec![test_s, t_s, f_s].join("\n").parse()?; + let operation = caps["operation"].parse()?; + let test = Test( + caps["div"].parse()?, + caps["if_1"].parse()?, + caps["if_0"].parse()?, + ); Ok(Monkey { items,