aoc-rs-2021/src/day_18/parsing.rs
Jan Christian Grünhage c49814908e implement day 18
2021-12-18 18:08:53 +01:00

69 lines
1.7 KiB
Rust

use yap::Tokens;
use crate::parsing::{newline, parse_digit};
use super::model::SnailfishNumber;
pub fn parse_regular(tokens: &mut impl Tokens<Item = char>) -> Option<SnailfishNumber> {
parse_digit(tokens).map(|digit: isize| digit.into())
}
pub fn parse_pair(tokens: &mut impl Tokens<Item = char>) -> Option<SnailfishNumber> {
tokens.optional(|t| {
if !t.token('[') {
return None;
}
let lhs = parse_snailfish_number(t)?;
if !t.token(',') {
return None;
}
let rhs = parse_snailfish_number(t)?;
if !t.token(']') {
return None;
}
Some((lhs, rhs).into())
})
}
pub fn parse_snailfish_number(tokens: &mut impl Tokens<Item = char>) -> Option<SnailfishNumber> {
yap::one_of!(t from tokens;
parse_regular(t),
parse_pair(t),
)
}
pub fn parse_number_list(tokens: &mut impl Tokens<Item = char>) -> Option<Vec<SnailfishNumber>> {
tokens.optional(|t| {
let vec: Vec<SnailfishNumber> = t
.sep_by(|t| parse_snailfish_number(t), |t| newline(t))
.collect();
if !vec.is_empty() {
Some(vec)
} else {
None
}
})
}
#[cfg(test)]
mod test {
use yap::IntoTokens;
#[test]
fn test_parsing() {
let number = super::parse_snailfish_number(
&mut "[[[[1,3],[5,3]],[[1,3],[8,7]]],[[[4,9],[6,9]],[[8,2],[7,3]]]]".into_tokens(),
);
assert_eq!(
number,
Some(
(
(((1, 3), (5, 3)), ((1, 3), (8, 7))),
(((4, 9), (6, 9)), ((8, 2), (7, 3)))
)
.into()
)
);
}
}