From 168479c5b118d4efc44de5f4898ce7a641e712a6 Mon Sep 17 00:00:00 2001 From: JonOfUs Date: Sat, 10 Dec 2022 13:33:11 +0100 Subject: [PATCH] Day 9 - part 2 --- src/days/d09.rs | 100 ++++++++++++++++++++---------------------------- 1 file changed, 42 insertions(+), 58 deletions(-) diff --git a/src/days/d09.rs b/src/days/d09.rs index d320e25..35a07db 100644 --- a/src/days/d09.rs +++ b/src/days/d09.rs @@ -1,9 +1,9 @@ use std::fs; -const GRID_WIDTH: u32 = 1000; -const GRID_HEIGHT: u32 = 1000; -const START_X: u32 = 500; -const START_Y: u32 = 500; +const GRID_WIDTH: i32 = 1000; +const GRID_HEIGHT: i32 = 1000; +const START_X: i32 = 500; +const START_Y: i32 = 500; pub fn solve() { @@ -32,7 +32,7 @@ pub fn solve() { "R" => Dir::Right, _ => Dir::Up }; - let amount = cmd[1].parse::().unwrap(); + let amount = cmd[1].parse::().unwrap(); // move head for _ in 0..amount { @@ -62,13 +62,13 @@ enum Dir { } struct Rope { - knots_x: Vec, - knots_y: Vec, + knots_x: Vec, + knots_y: Vec, tail_visited_grid: Vec> // [Y][X] } impl Rope { - pub fn new(knots: u32) -> Self { + pub fn new(knots: i32) -> Self { Rope { knots_x: (0..knots).map(|_| START_X).collect(), knots_y: (0..knots).map(|_| START_Y).collect(), @@ -102,67 +102,51 @@ impl Rope { fn check_tail_pos(&mut self) { // check pos of each knot except first for i in 1..self.knots_x.len() { - // head is too far top/bottom - if self.knots_x[i-1].abs_diff(self.knots_x[i]) > 1 { - // if necessary, move on Y-axis - self.knots_y[i] = self.knots_y[i-1]; - - if self.knots_x[i-1] > self.knots_x[i] { // head below - self.knots_x[i] = self.knots_x[i-1]-1; - } else { // head above - self.knots_x[i] = self.knots_x[i-1]+1; - } - } - - // head is too far left/right - else if self.knots_y[i-1].abs_diff(self.knots_y[i]) > 1 { - // if necessary, move on X-axis - self.knots_x[i] = self.knots_x[i-1]; - - if self.knots_y[i-1] > self.knots_y[i] { // head right - self.knots_y[i] = self.knots_y[i-1]-1; - } else { // head left - self.knots_y[i] = self.knots_y[i-1]+1; + if (self.knots_x[i-1] == self.knots_x[i] && (self.knots_y[i-1] - self.knots_y[i]).abs() == 1) + || (self.knots_y[i-1] == self.knots_y[i] && (self.knots_x[i-1] - self.knots_x[i]).abs() == 1) { + // Knots are touching, nothing to do + } else if (self.knots_x[i-1] - self.knots_x[i]).abs() == 1 && (self.knots_y[i-1] - self.knots_y[i]).abs() == 1 { + // Knots are touching diagonally, nothing to do + } else { + // Tail needs to be moved + if self.knots_x[i-1] != self.knots_x[i] && self.knots_y[i-1] != self.knots_y[i] { + // Move diagonally + self.knots_x[i] += normalize(self.knots_x[i-1] - self.knots_x[i]); + self.knots_y[i] += normalize(self.knots_y[i-1] - self.knots_y[i]); + } else { + // Move vertically/horizontally + if self.knots_x[i-1] == self.knots_x[i] { + self.knots_y[i] += normalize(self.knots_y[i-1] - self.knots_y[i]); + } else { + self.knots_x[i] += normalize(self.knots_x[i-1] - self.knots_x[i]); + } } } } - // set current tail (last knot) pos as visited - self.tail_visited_grid[*self.knots_y.last().unwrap() as usize][*self.knots_x.last().unwrap() as usize] = true; - - /* - let min_x = self.knots_x.iter().min().unwrap(); - let max_x = self.knots_x.iter().max().unwrap(); - let min_y = self.knots_y.iter().min().unwrap(); - let max_y = self.knots_y.iter().max().unwrap(); - - let width = max_x - min_x + 1; - let height = max_y - min_y + 1; - - let mut out: Vec> = (0..height).map(|_| (0..width).map(|_| ".".to_string()).collect()).collect(); - for i in (0..self.knots_x.len()).rev() { - let x = self.knots_x[i]-min_x; - let y = self.knots_y[i]-min_y; - out[y as usize][x as usize] = i.to_string(); - } - println!("{}", min_y); - out.iter().for_each(|line| { - line.iter().for_each(|o| print!("{}",o)); - println!(); - }); - println!();*/ - + // Set current tail (last knot) pos as visited + self.tail_visited_grid[*self.knots_y.last().unwrap() as usize][*self.knots_x.last().unwrap() as usize] = true; } // returns number of cells visited by tail - pub fn tail_visited_num(&self) -> u32 { + pub fn tail_visited_num(&self) -> i32 { self.tail_visited_grid.iter() .map(|row| row.iter() .map(|cell| - if *cell { 1 as u32 } - else { 0 as u32 } - ).sum::() + if *cell { 1 as i32 } + else { 0 as i32 } + ).sum::() ).sum() } +} + +fn normalize(n: i32) -> i32 { + if n > 0 { + 1 + } else if n < 0 { + -1 + } else { + 0 + } } \ No newline at end of file