diff options
author | Prefetch | 2023-02-25 11:41:27 +0100 |
---|---|---|
committer | Prefetch | 2023-02-25 11:41:27 +0100 |
commit | 3b877bf4cc667eb8bcc787d145203600a4dba2d2 (patch) | |
tree | c1d247def29fcb58ae28e4ae4e4d73d1b4e1b27f /d07/src |
Initial commit
Diffstat (limited to 'd07/src')
-rw-r--r-- | d07/src/main.rs | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/d07/src/main.rs b/d07/src/main.rs new file mode 100644 index 0000000..ef53b6e --- /dev/null +++ b/d07/src/main.rs @@ -0,0 +1,153 @@ +use std::fs; + +fn solve_part1(lines: &Vec<&str>) -> usize { + let mut total_tls = 0; + + for line in lines { + let chars: Vec<char> = line.chars().collect(); + + let mut has_tls = false; + let mut in_brackets = false; + for i in 0..chars.len() - 3 { + // Are we entering/leaving a "hypernet sequence"? + if chars[i] == '[' { + in_brackets = true; + } else if chars[i] == ']' { + in_brackets = false; + } + + // Check for ABBA pattern to know if address has TLS + let ch0 = chars[i]; + let ch1 = chars[i + 1]; + if ch0 != ch1 && chars[i + 3] == ch0 && chars[i + 2] == ch1 { + if !in_brackets { + has_tls = true; + } else { + // Reject if an ABBA occurs in brackets + has_tls = false; + break; + } + } + } + + if has_tls { + total_tls += 1; + } + } + + total_tls +} + +fn solve_part2(lines: &Vec<&str>) -> usize { + let mut total_ssl = 0; + + for line in lines { + let chars: Vec<char> = line.chars().collect(); + + let mut has_ssl = false; + let mut in_brack_aba = false; + 'outer: for i in 0..chars.len() - 2 { + // Are we entering/leaving brackets on our ABA search? + if chars[i] == '[' { + in_brack_aba = true; + } else if chars[i] == ']' { + in_brack_aba = false; + } + + // Check for ABA pattern + let ch0 = chars[i]; + let ch1 = chars[i + 1]; + if !in_brack_aba && ch0 != ch1 && chars[i + 2] == ch0 { + // If ABA was found, check entire address for BAB + let mut in_brack_bab = false; + for j in 0..chars.len() - 2 { + // Are we entering/leaving brackets on our BAB search? + if chars[j] == '[' { + in_brack_bab = true; + } else if chars[j] == ']' { + in_brack_bab = false; + } + + if chars[j] == ch1 && chars[j + 1] == ch0 && chars[j + 2] == ch1 { + // BAB must be in square brackets + if in_brack_bab { + has_ssl = true; + break 'outer; + } + } + } + } + } + + if has_ssl { + total_ssl += 1; + } + } + + total_ssl +} + +fn main() { + // Read address list from input text file + let input = fs::read_to_string("input.txt").unwrap(); + let lines = input.lines().collect(); + + // Part 1 gives 118 for me + println!("Part 1 solution: {}", solve_part1(&lines)); + + // Part 2 gives 260 for me + println!("Part 2 solution: {}", solve_part2(&lines)); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn part1_example1() { + let lines = vec!["abba[mnop]qrst"]; + assert_eq!(solve_part1(&lines), 1); + } + + #[test] + fn part1_example2() { + let lines = vec!["abcd[bddb]xyyx"]; + assert_eq!(solve_part1(&lines), 0); + } + + #[test] + fn part1_example3() { + let lines = vec!["aaaa[qwer]tyui"]; + assert_eq!(solve_part1(&lines), 0); + } + + #[test] + fn part1_example4() { + let lines = vec!["ioxxoj[asdfgh]zxcvbn"]; + assert_eq!(solve_part1(&lines), 1); + } + + #[test] + fn part2_example1() { + let lines = vec!["aba[bab]xyz"]; + assert_eq!(solve_part2(&lines), 1); + } + + #[test] + fn part2_example2() { + let lines = vec!["xyx[xyx]xyx"]; + assert_eq!(solve_part2(&lines), 0); + } + + #[test] + fn part2_example3() { + let lines = vec!["aaa[kek]eke"]; + assert_eq!(solve_part2(&lines), 1); + } + + #[test] + fn part2_example4() { + let lines = vec!["zazbz[bzb]cdb"]; + assert_eq!(solve_part2(&lines), 1); + } +} |