diff --git a/2017/rust/src/day_06.rs b/2017/rust/src/day_06.rs new file mode 100644 index 0000000..e1ddb9d --- /dev/null +++ b/2017/rust/src/day_06.rs @@ -0,0 +1,69 @@ +use std::collections::HashSet; +use failure::*; + +pub fn solve(input: &str) -> Result { + let banks: Vec<_> = input + .split_whitespace() + .map(str::parse) + .collect::>()?; + + let mut reallocation = Reallocation { banks: banks.clone() }; + let cycles = unique_cycles(reallocation); + + reallocation = Reallocation { banks }; + Ok((unique_cycles(reallocation.skip(cycles - 1)) - 1).to_string()) +} + +fn unique_cycles>>(reallocation: R) -> usize { + let mut seen = HashSet::new(); + for (i, banks) in reallocation.enumerate() { + if seen.contains(&banks) { + return i + 1; + } + + seen.insert(banks.clone()); + } + unreachable!(); +} + +#[test] +fn test_part_one() { + let reallocation = Reallocation { banks: vec![0, 2, 7, 0] }; + assert_eq!(unique_cycles(reallocation), 5); +} + +struct Reallocation { + banks: Vec, +} + +impl Iterator for Reallocation { + type Item = Vec; + + fn next(&mut self) -> Option { + let banks = self.banks.clone(); + let mut banks: Vec<_> = banks.iter().enumerate().collect(); + banks.reverse(); + let (start, max) = banks + .iter() + .max_by_key(|&&(_, x)| x) + .map(|&(i, x)| (i, x.clone()))?; + + let len = self.banks.len(); + self.banks[start] = 0; + for i in 1..=max { + self.banks[(start + i) % len] += 1; + } + + Some(self.banks.clone()) + } +} + +#[test] +fn test_reallocation() { + let mut r = Reallocation { + banks: vec![0, 2, 7, 0], + }; + assert_eq!(r.next(), Some(vec![2, 4, 1, 2])); + assert_eq!(r.next(), Some(vec![3, 1, 2, 3])); + assert_eq!(r.next(), Some(vec![0, 2, 3, 4])); +} diff --git a/2017/rust/src/day_15.rs b/2017/rust/src/day_15.rs index c429d43..e6a9544 100644 --- a/2017/rust/src/day_15.rs +++ b/2017/rust/src/day_15.rs @@ -1,6 +1,7 @@ use failure::*; use regex::Regex; +#[allow(dead_code)] pub fn solve(input: &str) -> Result { let re: Regex = Regex::new(r"\d+")?; let matches: Vec<_> = re.find_iter(input) diff --git a/2017/rust/src/main.rs b/2017/rust/src/main.rs index ff8c10f..6eb8141 100644 --- a/2017/rust/src/main.rs +++ b/2017/rust/src/main.rs @@ -1,4 +1,4 @@ -#![feature(conservative_impl_trait)] +#![feature(conservative_impl_trait, inclusive_range_syntax)] extern crate failure; #[macro_use] @@ -14,6 +14,7 @@ mod day_02; mod day_03; mod day_04; mod day_05; +mod day_06; mod day_15; fn main() { @@ -26,7 +27,7 @@ fn run() -> Result<(), Error> { let mut input = String::new(); io::stdin().read_to_string(&mut input)?; - let solution = day_15::solve(&input)?; + let solution = day_06::solve(&input)?; println!("{}", solution); Ok(())