2022 day11/rust: clean up parsing

This commit is contained in:
Xiretza 2022-12-11 17:58:18 +01:00
parent 77e443e6c8
commit 8a48ba05b0

View file

@ -22,6 +22,17 @@ impl Operand {
}
}
impl FromStr for Operand {
type Err = std::num::ParseIntError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
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<Self, Self::Err> {
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::<Result<_, _>>()?;
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,