aoc-rs-2021/src/day_13/parsing.rs
Jan Christian Grünhage d0216fda25 implement day 13
2021-12-13 07:35:55 +01:00

53 lines
1.5 KiB
Rust

use yap::Tokens;
use crate::parsing::{newline, parse_n, parse_number};
use super::{Fold, Grid, Input, Point};
pub fn parse_fold(tokens: &mut impl Tokens<Item = char>) -> Option<Fold> {
yap::one_of!(ts from tokens;
ts.tokens("fold along y=".chars()).then(|| parse_number(ts).map(Fold::Y)).flatten(),
ts.tokens("fold along x=".chars()).then(|| parse_number(ts).map(Fold::X)).flatten(),
)
}
pub fn parse_point(tokens: &mut impl Tokens<Item = char>) -> Option<Point> {
parse_n(tokens, |t| parse_number(t), |t| t.token(',')).map(|point: [usize; 2]| Point {
x: point[0],
y: point[1],
})
}
pub fn parse_input(tokens: &mut impl Tokens<Item = char>) -> Option<Input> {
let points: Vec<Point> = tokens.sep_by(|t| parse_point(t), |t| newline(t)).collect();
if points.is_empty() {
return None;
}
tokens.skip_many(|t| newline(t));
let instructions: Vec<Fold> = tokens.sep_by(|t| parse_fold(t), |t| newline(t)).collect();
if instructions.is_empty() {
return None;
}
let grid = Grid::new(&points);
Some(Input { grid, instructions })
}
#[cfg(test)]
mod test {
use yap::IntoTokens;
use crate::day_13::Fold;
#[test]
fn parse_fold() {
assert_eq!(
super::parse_fold(&mut "fold along y=7".into_tokens()),
Some(Fold::Y(7)),
);
assert_eq!(
super::parse_fold(&mut "fold along x=5".into_tokens()),
Some(Fold::X(5)),
);
}
}