diff --git a/2020/README.md b/2020/README.md index 8c233ed..9b928a0 100644 --- a/2020/README.md +++ b/2020/README.md @@ -24,10 +24,14 @@ Day 1 - Part 2 : 165026160 ``` AOC 2020 Day 2 - Part 1 : 640 - generator: 1.821498ms, - runner: 115.525µs + generator: 1.732103ms, + runner: 100.802µs + +Day 2 - Part 1 - handrolled : 640 + generator: 157.527µs, + runner: 97.775µs Day 2 - Part 2 : 472 - generator: 1.52241ms, - runner: 10.459µs + generator: 1.374162ms, + runner: 10.461µs ``` diff --git a/2020/src/day2.rs b/2020/src/day2.rs index 9410887..0328cbc 100644 --- a/2020/src/day2.rs +++ b/2020/src/day2.rs @@ -44,7 +44,7 @@ struct Policy { } #[aoc_generator(day2)] -fn parse(input: &str) -> Vec { +fn parse_regex(input: &str) -> Vec { let re = Regex::new(r"(\d+)-(\d+) (\w): (.*)").expect("Failed to compile regex"); input .split('\n') @@ -61,6 +61,38 @@ fn parse(input: &str) -> Vec { .collect() } +#[aoc_generator(day2, part1, handrolled)] +fn parse_handrolled(input: &str) -> Vec { + // 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()?; + + 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 + 2; + let password = line[start..].to_string(); + + Some(Policy { + min, + max, + letter, + password, + }) + }) + .collect() +} + fn is_valid_policy_part1(p: &Policy) -> bool { let c = p.password.matches(&p.letter).count(); p.min <= c && c <= p.max @@ -71,6 +103,11 @@ fn valid_policy_count_part1(policies: &[Policy]) -> usize { policies.iter().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 is_valid_policy_part2(p: &Policy) -> bool { let letter = Some(p.letter.as_str()); // Password system uses it 1 based numbering, so we -1 to get zero based. @@ -97,38 +134,37 @@ mod tests { "#; #[test] fn parse_policies() { - assert_eq!( - parse(INPUT), - vec![ - Policy { - min: 1, - max: 3, - letter: "a".to_string(), - password: "abcde".to_string(), - }, - Policy { - min: 1, - max: 3, - letter: "b".to_string(), - password: "cdefg".to_string(), - }, - Policy { - min: 2, - max: 9, - letter: "c".to_string(), - password: "ccccccccc".to_string(), - }, - ] - ); + let want = vec![ + Policy { + min: 1, + max: 3, + letter: "a".to_string(), + password: "abcde".to_string(), + }, + Policy { + min: 1, + max: 3, + letter: "b".to_string(), + password: "cdefg".to_string(), + }, + Policy { + min: 2, + max: 9, + letter: "c".to_string(), + password: "ccccccccc".to_string(), + }, + ]; + assert_eq!(parse_regex(INPUT), want); + assert_eq!(parse_handrolled(INPUT), want); } #[test] fn validate_count_part1() { - assert_eq!(valid_policy_count_part1(&parse(INPUT)), 2); + assert_eq!(valid_policy_count_part1(&parse_regex(INPUT)), 2); } #[test] fn validate_count_part2() { - assert_eq!(valid_policy_count_part2(&parse(INPUT)), 1); + assert_eq!(valid_policy_count_part2(&parse_regex(INPUT)), 1); } }