From fc9a217119293918e94a0d0d983cdb291803f88f Mon Sep 17 00:00:00 2001 From: Justin Worthe Date: Wed, 6 Dec 2017 08:01:52 +0200 Subject: Day 6: memory rebalancing --- src/bin/day_6.rs | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 3 +++ 2 files changed, 64 insertions(+) create mode 100644 src/bin/day_6.rs (limited to 'src') diff --git a/src/bin/day_6.rs b/src/bin/day_6.rs new file mode 100644 index 0000000..be9a515 --- /dev/null +++ b/src/bin/day_6.rs @@ -0,0 +1,61 @@ +extern crate advent_of_code_2017; +use advent_of_code_2017::*; + +fn main() { + let args = AdventArgs::init(); + + let init_layout = parse_space_separated_ints(&args.input[0]).unwrap(); + + let mut layouts = vec!(init_layout); + let mut balances = 0; + let mut cycle_found = false; + let mut cycle_size = 0; + + while !cycle_found { + balances += 1; + let new_layout = find_next_layout(&layouts); + + if let Some(index) = layouts.iter().position(|x| *x == new_layout) { + cycle_found = true; + cycle_size = layouts.len() - index; + }; + + layouts.push(new_layout); + } + + if args.part == 1 { + println!("Did {} rebalances", balances); + } else { + println!("Cycle was {} long", cycle_size); + } +} + +fn find_next_layout(layouts: &Vec>) -> Vec { + let previous_layout = layouts.last().unwrap(); + rebalance(&previous_layout) +} + +fn rebalance(layout: &Vec) -> Vec { + let biggest_container = layout.iter() + .enumerate() + .max_by(|&(ai, &asize), &(bi, &bsize)| { + asize.cmp(&bsize).then(bi.cmp(&ai)) + }) + .map(|(i, _)| i) + .unwrap(); + + + let mut new_layout = layout.clone(); + let mut to_redistribute = new_layout[biggest_container]; + new_layout[biggest_container] = 0; + let mut target = (biggest_container + 1) % layout.len(); + + while to_redistribute > 0 { + new_layout[target] += 1; + to_redistribute -= 1; + target = (target + 1) % layout.len(); + } + + new_layout +} + diff --git a/src/lib.rs b/src/lib.rs index caa8881..2a7b73a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -62,6 +62,9 @@ impl AdventArgs { pub fn one_number_input(&self) -> Result { self.input[0].parse() } + pub fn number_per_line_input(&self) -> Result, std::num::ParseIntError> { + self.input.iter().map(|line| line.parse()).collect() + } } pub fn parse_space_separated_ints(line: &String) -> Result, std::num::ParseIntError> { -- cgit v1.2.3