1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
use crate::input::Input;
use std::collections::HashSet;
fn has_abba(ip: &&str) -> bool {
let ip_bytes = ip.as_bytes();
let mut in_hypernet_sequence = false;
let mut has_abba = false;
for (idx, &c) in ip_bytes.iter().enumerate() {
if c == b'[' {
in_hypernet_sequence = true;
} else if c == b']' {
in_hypernet_sequence = false;
} else if ip_bytes.len() > idx + 3
&& ip_bytes[idx + 3] == c
&& ip_bytes[idx + 1] != c
&& ip_bytes[idx + 1] == ip_bytes[idx + 2]
{
if in_hypernet_sequence {
return false;
} else {
has_abba = true;
}
}
}
has_abba
}
fn supports_ssl(ip: &&str) -> bool {
let ip_bytes = ip.as_bytes();
let mut in_hypernet_sequence = false;
let mut abas = HashSet::new();
let mut babs = HashSet::new();
for (idx, &c) in ip_bytes.iter().enumerate() {
if c == b'[' {
in_hypernet_sequence = true;
} else if c == b']' {
in_hypernet_sequence = false;
} else if ip_bytes.len() > idx + 2 && ip_bytes[idx + 2] == c && ip_bytes[idx + 1] != c {
if in_hypernet_sequence {
abas.insert((c, ip_bytes[idx + 1]));
} else {
babs.insert((ip_bytes[idx + 1], c));
}
}
}
abas.intersection(&babs).count() > 0
}
pub fn solve(input: &mut Input) -> Result<usize, String> {
Ok(input
.text
.lines()
.filter(if input.is_part_one() {
has_abba
} else {
supports_ssl
})
.count())
}
#[test]
pub fn tests() {
use crate::input::{test_part_one, test_part_two};
test_part_one!("abba[mnop]qrst" => 1);
test_part_one!("abcd[bddb]xyyx" => 0);
test_part_one!("aaaa[qwer]tyui" => 0);
test_part_one!("ioxxoj[asdfgh]zxcvbn" => 1);
test_part_two!("aba[bab]xyz" => 1);
test_part_two!("xyx[xyx]xyx" => 0);
test_part_two!("aaa[kek]eke" => 1);
test_part_two!("zazbz[bzb]cdb" => 1);
let real_input = include_str!("day07_input.txt");
test_part_one!(real_input => 105);
test_part_two!(real_input => 258);
}