From b5da2fa328ad63d683d66da65e656ed2ee64878c Mon Sep 17 00:00:00 2001 From: Curtis McEnroe Date: Mon, 27 Nov 2017 17:11:18 -0500 Subject: Move to 2016 directory --- 2016/src/bin/day07.rs | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 2016/src/bin/day07.rs (limited to '2016/src/bin/day07.rs') diff --git a/2016/src/bin/day07.rs b/2016/src/bin/day07.rs new file mode 100644 index 0000000..b4967ff --- /dev/null +++ b/2016/src/bin/day07.rs @@ -0,0 +1,119 @@ +use std::io::{self, Read}; +use std::str::FromStr; + +fn has_abba(s: &str) -> bool { + s.as_bytes() + .windows(4) + .any(|window| { + window[0] == window[3] + && window[1] == window[2] + && window[0] != window[1] + }) +} + +fn abas(s: &str) -> Vec<&[u8]> { + s.as_bytes() + .windows(3) + .filter(|window| { + window[0] == window[2] + && window[0] != window[1] + }) + .collect() +} + +fn has_bab(s: &str, aba: &[u8]) -> bool { + s.as_bytes() + .windows(3) + .any(|window| { + window[0] == aba[1] + && window[1] == aba[0] + && window[2] == aba[1] + }) +} + +#[derive(Default)] +struct Ip { + supernet: Vec, + hypernet: Vec, +} + +impl Ip { + fn supports_tls(&self) -> bool { + self.supernet.iter().any(|s| has_abba(s)) + && !self.hypernet.iter().any(|s| has_abba(s)) + } + + fn supports_ssl(&self) -> bool { + self.supernet + .iter() + .flat_map(|s| abas(s)) + .any(|aba| { + self.hypernet + .iter() + .any(|s| has_bab(s, aba)) + }) + } +} + +impl FromStr for Ip { + type Err = (); + fn from_str(s: &str) -> Result { + let mut ip = Ip::default(); + + for (i, seq) in s.split(|ch| ch == '[' || ch == ']').enumerate() { + if i % 2 == 0 { + ip.supernet.push(seq.to_owned()); + } else { + ip.hypernet.push(seq.to_owned()); + } + } + + Ok(ip) + } +} + +fn solve1(input: &str) -> usize { + input.lines() + .map(str::parse) + .map(Result::unwrap) + .filter(Ip::supports_tls) + .count() +} + +fn solve2(input: &str) -> usize { + input.lines() + .map(str::parse) + .map(Result::unwrap) + .filter(Ip::supports_ssl) + .count() +} + +fn main() { + let mut input = String::new(); + io::stdin().read_to_string(&mut input).unwrap(); + + println!("Part 1: {}", solve1(&input)); + println!("Part 2: {}", solve2(&input)); +} + +#[test] +fn part1() { + let input = " +abba[mnop]qrst +abcd[bddb]xyyx +aaaa[qwer]tyui +ioxxoj[asdfgh]zxcvbn +"; + assert_eq!(2, solve1(input.trim())); +} + +#[test] +fn part2() { + let input = " +aba[bab]xyz +xyx[xyx]xyx +aaa[kek]eke +zazbz[bzb]cdb +"; + assert_eq!(3, solve2(input.trim())); +} -- cgit 1.4.1