[2018][rust][05.1]
change xyvrlpyxunttkrvknuxmuuylyvklzwzl
commit f9a62fa9ef5e674b7518170f156d6eb1bae8ac2e
author Alpha Chen <alpha.chen@gmail.com>
date
parent xkumxxor
diff --git a/2018/rust/Cargo.lock b/2018/rust/Cargo.lock
index 1da7712..0bd80e1 100644
--- a/2018/rust/Cargo.lock
+++ b/2018/rust/Cargo.lock
@@ -2,6 +2,7 @@
 name = "advent_of_code_2018"
 version = "0.1.0"
 dependencies = [
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "pest 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "pest_derive 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/2018/rust/Cargo.toml b/2018/rust/Cargo.toml
index 40a1311..5281b4b 100644
--- a/2018/rust/Cargo.toml
+++ b/2018/rust/Cargo.toml
@@ -5,6 +5,7 @@ authors = ["Alpha Chen <alpha.chen@gmail.com>"]
 edition = "2018"
 
 [dependencies]
+lazy_static = "1.2.0"
 pest = "2.0"
 pest_derive = "2.0"
 regex = "1"
diff --git a/2018/rust/src/bin/day_05.rs b/2018/rust/src/bin/day_05.rs
new file mode 100644
index 0000000..b0d0343
--- /dev/null
+++ b/2018/rust/src/bin/day_05.rs
@@ -0,0 +1,83 @@
+use std::error::Error;
+use std::io::{self, Read};
+
+use lazy_static::lazy_static;
+use regex::Regex;
+
+fn main() -> Result<(), Box<Error>> {
+    let mut input = String::new();
+    io::stdin().read_to_string(&mut input)?;
+
+    let output = solve(&input)?;
+    println!("{}", output);
+
+    Ok(())
+}
+
+fn solve(input: &str) -> Result<String, Box<Error>> {
+    let reaction = Reaction {
+        polymer: input.trim().into(),
+    };
+    Ok(reaction.last().map(|x| x.len().to_string()).unwrap())
+}
+
+#[test]
+fn test_solve() {
+    let input = "dabAcCaCBAcCcaDA";
+
+    let output = solve(input).unwrap();
+
+    // Part One
+    assert_eq!(output, "10".to_string());
+}
+
+struct Reaction {
+    polymer: String,
+}
+
+impl Iterator for Reaction {
+    type Item = String;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        lazy_static! {
+            static ref RE: Regex = {
+                let re: String = (b'a'..=b'z')
+                    .map(|x| x as char)
+                    .flat_map(|x| {
+                        vec![
+                            format!("{}{}", x, x.to_uppercase()),
+                            format!("{}{}", x.to_uppercase(), x),
+                        ]
+                    })
+                    .collect::<Vec<_>>()
+                    .join("|");
+                Regex::new(&re).unwrap()
+            };
+        }
+
+        let current = self.polymer.clone();
+        self.polymer = RE.replace(&self.polymer, "").into();
+        if self.polymer == current {
+            None
+        } else {
+            Some(self.polymer.to_string())
+        }
+    }
+}
+
+#[test]
+fn test_reaction() {
+    let polymer = "dabAcCaCBAcCcaDA".into();
+    let mut reaction = Reaction { polymer };
+
+    let polymer = reaction.next().unwrap();
+    assert_eq!(polymer, "dabAaCBAcCcaDA".to_string());
+
+    let polymer = reaction.next().unwrap();
+    assert_eq!(polymer, "dabCBAcCcaDA".to_string());
+
+    let polymer = reaction.next().unwrap();
+    assert_eq!(polymer, "dabCBAcaDA".to_string());
+
+    assert_eq!(reaction.next(), Option::None);
+}