diff --git a/2020/src/day2.rs b/2020/src/day2.rs index 0328cbc..10762b8 100644 --- a/2020/src/day2.rs +++ b/2020/src/day2.rs @@ -44,53 +44,48 @@ struct Policy { } #[aoc_generator(day2)] -fn parse_regex(input: &str) -> Vec { +fn parse_regex<'a>(input: &'a str) -> impl Iterator + 'a { let re = Regex::new(r"(\d+)-(\d+) (\w): (.*)").expect("Failed to compile regex"); input .split('\n') - .filter(|line| re.is_match(line)) - .map(|line| { - let caps = re.captures(line).expect("Failed to match pattern"); - Policy { + .filter_map(move |line| match re.captures(line) { + Some(caps) => Some(Policy { min: caps.get(1).unwrap().as_str().parse().unwrap(), max: caps.get(2).unwrap().as_str().parse().unwrap(), letter: caps.get(3).unwrap().as_str().to_string(), password: caps.get(4).unwrap().as_str().to_string(), - } + }), + None => None, }) - .collect() } #[aoc_generator(day2, part1, handrolled)] -fn parse_handrolled(input: &str) -> Vec { +fn parse_handrolled<'a>(input: &'a str) -> impl Iterator + 'a { // Example line: // 1-3 a: abcde - input - .split('\n') - .filter_map(|line| { - let start = 0; - let end = line.find('-')?; - let min: usize = line[start..end].parse().ok()?; + input.split('\n').filter_map(|line| { + let start = 0; + let end = line.find('-')?; + let min: usize = line[start..end].parse().ok()?; - let start = end + 1; - let end = line.find(' ')?; - let max: usize = line[start..end].parse().ok()?; + let start = end + 1; + let end = line.find(' ')?; + let max: usize = line[start..end].parse().ok()?; - let start = end + 1; - let end = line.find(':')?; - let letter = line[start..end].to_string(); + let start = end + 1; + let end = line.find(':')?; + let letter = line[start..end].to_string(); - let start = end + 2; - let password = line[start..].to_string(); + let start = end + 2; + let password = line[start..].to_string(); - Some(Policy { - min, - max, - letter, - password, - }) + Some(Policy { + min, + max, + letter, + password, }) - .collect() + }) } fn is_valid_policy_part1(p: &Policy) -> bool { @@ -99,13 +94,13 @@ fn is_valid_policy_part1(p: &Policy) -> bool { } #[aoc(day2, part1)] -fn valid_policy_count_part1(policies: &[Policy]) -> usize { - policies.iter().filter(|p| is_valid_policy_part1(p)).count() +fn valid_policy_count_part1(policies: &mut dyn Iterator) -> usize { + policies.filter(|p| is_valid_policy_part1(p)).count() } #[aoc(day2, part1, handrolled)] -fn valid_policy_count_handrolled_part1(policies: &[Policy]) -> usize { - policies.iter().filter(|p| is_valid_policy_part1(p)).count() +fn valid_policy_count_handrolled_part1(policies: &mut dyn Iterator) -> usize { + policies.filter(|p| is_valid_policy_part1(p)).count() } fn is_valid_policy_part2(p: &Policy) -> bool { @@ -119,8 +114,8 @@ fn is_valid_policy_part2(p: &Policy) -> bool { } #[aoc(day2, part2)] -fn valid_policy_count_part2(policies: &[Policy]) -> usize { - policies.iter().filter(|p| is_valid_policy_part2(p)).count() +fn valid_policy_count_part2(policies: &mut dyn Iterator) -> usize { + policies.filter(|p| is_valid_policy_part2(p)).count() } #[cfg(test)] @@ -154,17 +149,17 @@ mod tests { password: "ccccccccc".to_string(), }, ]; - assert_eq!(parse_regex(INPUT), want); - assert_eq!(parse_handrolled(INPUT), want); + assert_eq!(parse_regex(INPUT).collect::>(), want); + assert_eq!(parse_handrolled(INPUT).collect::>(), want); } #[test] fn validate_count_part1() { - assert_eq!(valid_policy_count_part1(&parse_regex(INPUT)), 2); + assert_eq!(valid_policy_count_part1(&mut parse_regex(INPUT)), 2); } #[test] fn validate_count_part2() { - assert_eq!(valid_policy_count_part2(&parse_regex(INPUT)), 1); + assert_eq!(valid_policy_count_part2(&mut parse_regex(INPUT)), 1); } }