53 lines
1.5 KiB
Rust
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)),
|
|
);
|
|
}
|
|
}
|