summaryrefslogtreecommitdiff
path: root/d07/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'd07/src/main.rs')
-rw-r--r--d07/src/main.rs153
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);
+ }
+}