advent_of_code_2022/day_01/src/parser.rs
2022-12-03 16:29:23 -05:00

61 lines
1.4 KiB
Rust

use nom::character::complete::{digit1, line_ending};
use nom::combinator::map_res;
use nom::multi::{count, separated_list0, separated_list1};
use nom::IResult;
fn elf_parser(s: &str) -> IResult<&str, usize> {
let (rest, matched): (&str, Vec<usize>) = separated_list0(line_ending, get_digits)(s)?;
Ok((rest, matched.iter().sum()))
}
fn get_digits(s: &str) -> IResult<&str, usize> {
map_res(digit1, str::parse::<usize>)(s)
}
fn all_elf_parse(inp: &str) -> IResult<&str, Vec<usize>> {
separated_list1(count(line_ending, 2), elf_parser)(inp)
}
pub fn parse(inp: String) -> Vec<usize> {
if let Ok((_, elves)) = all_elf_parse(&inp) {
elves.clone()
} else {
panic!()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_get_digits() {
assert_eq!(Ok(("", 123)), get_digits("123"));
}
#[test]
fn test_one_line_make_elf() {
assert_eq!(Ok(("", 123)), elf_parser("123"))
}
#[test]
fn test_multiline_make_elf() {
assert_eq!(Ok(("", 1368)), elf_parser("123\n456\n789"))
}
#[test]
fn test_multiple_elf() {
assert_eq!(
Ok(("\n\n123\n123", 1368)),
elf_parser("123\n456\n789\n\n123\n123")
)
}
#[test]
fn test_multiple_elf_parsed() {
assert_eq!(
Ok(("", vec![1368, 246])),
all_elf_parse("123\n456\n789\n\n123\n123")
)
}
}