diff --git a/README.md b/README.md index 3e2cc9b..52a9620 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,9 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www. | [Day 4](./src/bin/04.rs) | `152.1ms` | `242.8ms` | | [Day 5](./src/bin/05.rs) | `5.1s` | `11.7s` | | [Day 6](./src/bin/06.rs) | `384.1µs` | `396.5µs` | +| [Day 7](./src/bin/07.rs) | `1.5ms` | `1.3ms` | -**Total: 17196.56ms** +**Total: 17199.36ms** --- diff --git a/data/examples/07.txt b/data/examples/07.txt new file mode 100644 index 0000000..70cab61 --- /dev/null +++ b/data/examples/07.txt @@ -0,0 +1,4 @@ +abba[mnop]qrst +abcd[bddb]xyyx +aaaa[qwer]tyui +ioxxoj[asdfgh]zxcvbn diff --git a/src/bin/07.rs b/src/bin/07.rs new file mode 100644 index 0000000..aa993c2 --- /dev/null +++ b/src/bin/07.rs @@ -0,0 +1,96 @@ +advent_of_code::solution!(7); + +fn supports_tls(input: &&str) -> bool { + let input: Vec = input.chars().collect(); + let mut has_abba: bool = false; + let mut is_hypernet: bool = false; + for c in 0..(input.len() - 3) { + match input[c] { + '[' => is_hypernet = true, + ']' => is_hypernet = false, + _ => { + if input[c] == input[c + 3] + && input[c + 1] == input[c + 2] + && input[c] != input[c + 1] + { + if is_hypernet { + return false; + } + has_abba = true; + } + } + } + } + has_abba +} + +fn supports_ssl(input: &&str) -> bool { + let input: Vec = input.chars().collect(); + let mut is_hypernet: bool = false; + let mut abas: Vec<(char, char)> = Vec::new(); + let mut babs: Vec<(char, char)> = Vec::new(); + + for c in 0..(input.len() - 2) { + match input[c] { + '[' => is_hypernet = true, + ']' => is_hypernet = false, + _ => { + if input[c] == input[c + 2] + && input[c + 1] != input[c] + && input[c + 1] != '[' + && input[c + 1] != ']' + { + let pair = (input[c], input[c + 1]); + if is_hypernet { + babs.push(pair); + } else { + abas.push(pair); + } + } + } + } + } + + for pat in abas { + let rev_pat = (pat.1, pat.0); + if babs.contains(&rev_pat) { + return true; + } + } + false +} + +fn count_matching_ips(input: &str, func: &dyn Fn(&&str) -> bool) -> Option { + input + .strip_suffix("\n") + .unwrap_or(input) + .split("\n") + .filter(func) + .count() + .into() +} + +pub fn part_one(input: &str) -> Option { + count_matching_ips(input, &supports_tls) +} + +pub fn part_two(input: &str) -> Option { + count_matching_ips(input, &supports_ssl) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part_one() { + let result = part_one(&advent_of_code::template::read_file("examples", DAY)); + assert_eq!(result, Some(2)); + } + + #[test] + fn test_part_two() { + let result = part_two(&advent_of_code::template::read_file("examples", DAY)); + assert_eq!(result, Some(3)); + } +}