From fe66170e3edd28c0c2a58ce38ef17bd243e2b498 Mon Sep 17 00:00:00 2001 From: "max.nuding" Date: Fri, 9 Dec 2022 08:46:16 +0100 Subject: [PATCH] Simulate chains simultaneously --- src/day09/mod.rs | 84 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 56 insertions(+), 28 deletions(-) diff --git a/src/day09/mod.rs b/src/day09/mod.rs index 8a2c6fe..34bc8e3 100644 --- a/src/day09/mod.rs +++ b/src/day09/mod.rs @@ -1,5 +1,6 @@ use crate::read; use std::collections::HashSet; +use itertools::Itertools; #[derive(Debug, PartialEq, Eq, Default, Clone, Hash)] struct Position { @@ -59,43 +60,70 @@ impl Position { } } +struct Chain { + pub knots: Vec, + visited: HashSet +} + +impl Chain { + pub fn new(num_knots: usize) -> Self { + Self { + knots: vec![Position::default(); num_knots], + visited: HashSet::with_capacity(10000) + } + } + pub fn num_visited(&self) -> usize { + self.visited.len() + } + + pub fn move_knots(&mut self, direction: &str, count: usize) { + let move_head_func = match direction { + "R" => Position::move_right, + "U" => Position::move_up, + "L" => Position::move_left, + "D" => Position::move_down, + _ => unreachable!(), + }; + for _c in 0..count { + self.knots[0] = move_head_func(&mut self.knots[0]); + for i in 1..self.knots.len() { + self.knots[i] = self.knots[i].follow_head(&self.knots[i - 1]); + } + + self.visited.insert(self.knots.last().unwrap().clone()); + } + } +} + pub fn run() { + let res = simulate(vec![2, 10]); #[cfg(feature = "part1")] { - println!("Day 9, Part 01: {}", simulate(2)); + println!("Day 9, Part 01: {}", res[0]); } #[cfg(feature = "part2")] { - println!("Day 9, Part 02: {}", simulate(10)); + println!("Day 9, Part 02: {}", res[1]); } } -pub fn simulate(num_knots: usize) -> usize { - let mut visited: HashSet = HashSet::new(); - let mut knots = vec![Position::default(); num_knots]; - let input = read("09"); - let lines = input.lines(); - for line in lines { - if line.is_empty() { - continue; - } - let (dir, count) = line.split_once(' ').unwrap(); - let count = count.parse().unwrap(); - for _c in 0..count { - knots[0] = match dir { - "R" => knots[0].move_right(), - "U" => knots[0].move_up(), - "L" => knots[0].move_left(), - "D" => knots[0].move_down(), - _ => unreachable!(), - }; - for i in 1..knots.len() { - knots[i] = knots[i].follow_head(&knots[i - 1]); - } +fn simulate(chain_sizes: Vec) -> Vec { + let chains = read("09") + .lines() + .filter(|l|!l.is_empty()) + .map(|l|l.split_once(' ').unwrap()) + .map(|(dir, count)|(dir, count.parse::().unwrap())) + .fold(chain_sizes + .iter() + .map(|c|Chain::new(*c)) + .collect_vec(), + |mut chains, (dir, count)| { - visited.insert(knots.last().unwrap().clone()); - } - } - visited.len() + chains + .iter_mut() + .for_each(|chain|chain.move_knots(dir, count)); + chains + }); + chains.iter().map(|c|c.num_visited()).collect() }