use std::fs; fn solve_part1(lines: &Vec<&str>) -> usize { let mut total_tls = 0; for line in lines { let chars: Vec = 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 = 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); } }