From 8a48ba05b0b00db107a8ccc025f95e80caa353cd Mon Sep 17 00:00:00 2001 From: Xiretza Date: Sun, 11 Dec 2022 17:58:18 +0100 Subject: [PATCH] 2022 day11/rust: clean up parsing --- 2022/day11/rust/src/main.rs | 68 ++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/2022/day11/rust/src/main.rs b/2022/day11/rust/src/main.rs index e0522c0..fcb0f6d 100644 --- a/2022/day11/rust/src/main.rs +++ b/2022/day11/rust/src/main.rs @@ -22,6 +22,17 @@ impl Operand { } } +impl FromStr for Operand { + type Err = std::num::ParseIntError; + + fn from_str(s: &str) -> Result { + match s { + "old" => Ok(Operand::Old), + i => i.parse().map(Operand::Const), + } + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq)] enum Operation { Add(Operand), @@ -96,46 +107,39 @@ impl FromStr for Monkey { fn from_str(s: &str) -> Result { let mut lines = s.lines(); - lines.next().unwrap(); - let items: Vec<_> = lines - .next() - .unwrap() - .split_once(':') - .unwrap() - .1 - .trim() - .split(", ") - .map(|i| i.parse().unwrap()) - .map(|value| Item { value }) - .collect(); + lines.next().ok_or(())?; // Monkey n: - let op: Vec<_> = lines.next().unwrap().split_whitespace().collect(); - let (operand, op) = op.split_last().unwrap(); - let (operator, _) = op.split_last().unwrap(); - let operand = match *operand { - "old" => Operand::Old, - i => Operand::Const(i.parse().unwrap()), - }; - let operation = match *operator { + let mut with_prefix = |prefix: &str| lines.next().ok_or(())?.strip_prefix(prefix).ok_or(()); + let items: Vec<_> = with_prefix(" Starting items: ")? + .split(", ") + .map(|i| { + let value = i.parse().map_err(drop)?; + Ok(Item { value }) + }) + .collect::>()?; + + let (operator, operand) = with_prefix(" Operation: new = old ")? + .split_once(' ') + .ok_or(())?; + let operand = operand.parse().map_err(drop)?; + let operation = match operator { "+" => Operation::Add(operand), "*" => Operation::Multiply(operand), _ => panic!("invalid operator {operator}"), }; - let mut lastnum = || { - lines - .next() - .unwrap() - .split_whitespace() - .last() - .unwrap() + let test = Test::Divisible( + with_prefix(" Test: divisible by ")? .parse() - .unwrap() - }; - let test = Test::Divisible(lastnum()); + .map_err(drop)?, + ); - let target_pass = lastnum(); - let target_fail = lastnum(); + let target_pass = with_prefix(" If true: throw to monkey ")? + .parse() + .map_err(drop)?; + let target_fail = with_prefix(" If false: throw to monkey ")? + .parse() + .map_err(drop)?; Ok(Monkey { items,