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 "] 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> { + let mut input = String::new(); + io::stdin().read_to_string(&mut input)?; + + let output = solve(&input)?; + println!("{}", output); + + Ok(()) +} + +fn solve(input: &str) -> Result> { + 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 { + 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::>() + .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); +}