[2016][rust][7.0]
change nrlyvtxslkpywuvkwxmwnlkmxswnylol
commit 5466fea6512e14b0365537262fa000688a047b0f
author Alpha Chen <alpha.chen@gmail.com>
date
parent stxrlpls
diff --git a/2016/rust/src/day_07.rs b/2016/rust/src/day_07.rs
new file mode 100644
index 0000000..3a759cb
--- /dev/null
+++ b/2016/rust/src/day_07.rs
@@ -0,0 +1,78 @@
+use errors::*;
+
+pub fn solve(input: &str) -> Result<String> {
+  Ok(input.lines()
+    .map(|x| IP7::new(x))
+    .filter(IP7::supports_tls)
+    .count()
+    .to_string())
+}
+
+pub struct IP7 {
+  supernets: Vec<String>,
+  hypernets: Vec<String>,
+}
+
+impl IP7 {
+  fn new(s: &str) -> Self {
+    let mut current = String::new();
+    let mut supernets = Vec::new();
+    let mut hypernets = Vec::new();
+
+    for c in s.chars() {
+      match c {
+        '[' => {
+          supernets.push(current);
+          current = String::new();
+        }
+        ']' => {
+          hypernets.push(current);
+          current = String::new();
+        }
+        c => current.push(c),
+      }
+    }
+    supernets.push(current);
+
+    IP7 {
+      supernets: supernets,
+      hypernets: hypernets,
+    }
+  }
+
+  fn supports_tls(&self) -> bool {
+    self.supernets.iter().any(|x| Self::abba(x)) &&
+    self.hypernets.iter().all(|x| !Self::abba(x))
+  }
+
+  fn abba(s: &str) -> bool {
+    let v: Vec<_> = s.chars().collect();
+    v.windows(4).any(|w| (w[0] != w[1]) && (w[0] == w[3]) && (w[1] == w[2]))
+  }
+}
+
+#[cfg(test)]
+mod tests {
+  use super::*;
+
+  #[test]
+  fn test_new() {
+    let ip = IP7::new("abba[mnop]qrst");
+    assert_eq!(ip.supernets, vec!["abba".to_string(), "qrst".to_string()]);
+    assert_eq!(ip.hypernets, vec!["mnop".to_string()]);
+  }
+
+  #[test]
+  fn test_abba() {
+    assert!(IP7::abba("abba"));
+    assert!(!IP7::abba("abcd"));
+  }
+
+  #[test]
+  fn test_supports_tls() {
+    assert_eq!(IP7::new("abba[mnop]qrst").supports_tls(), true);
+    assert_eq!(IP7::new("abcd[bddb]xyyx").supports_tls(), false);
+    assert_eq!(IP7::new("aaaa[qwer]tyui").supports_tls(), false);
+    assert_eq!(IP7::new("ioxxoj[asdfgh]zxcvbn").supports_tls(), true);
+  }
+}
diff --git a/2016/rust/src/lib.rs b/2016/rust/src/lib.rs
index b9cc037..2e9fa82 100644
--- a/2016/rust/src/lib.rs
+++ b/2016/rust/src/lib.rs
@@ -12,3 +12,4 @@ pub mod day_03;
 pub mod day_04;
 pub mod day_05;
 pub mod day_06;
+pub mod day_07;
diff --git a/2016/rust/src/main.rs b/2016/rust/src/main.rs
index ad71ce8..ab72f40 100644
--- a/2016/rust/src/main.rs
+++ b/2016/rust/src/main.rs
@@ -10,7 +10,7 @@ fn main() {
     let mut input = String::new();
     io::stdin().read_to_string(&mut input).ok();
 
-    let solution = day_06::solve(&input)?;
+    let solution = day_07::solve(&input)?;
     println!("{}", solution);
 
     Ok(())