From 9ef31dde5576cef6b215d41134646c7314c732de Mon Sep 17 00:00:00 2001 From: Joseph Montanaro Date: Fri, 9 Dec 2022 22:41:21 -0800 Subject: [PATCH] finish day 9 --- 2022/src/day9.rs | 86 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 65 insertions(+), 21 deletions(-) diff --git a/2022/src/day9.rs b/2022/src/day9.rs index 6207864..0a4f710 100644 --- a/2022/src/day9.rs +++ b/2022/src/day9.rs @@ -1,4 +1,5 @@ use std::collections::HashSet; +use std::fmt::{Display, Formatter}; use std::str::FromStr; @@ -35,14 +36,14 @@ struct Pos { #[derive(Debug)] struct Rope { knots: [Pos; L], - tail_visited: HashSet + tail_visited: HashSet, } impl Rope { fn new() -> Self { Rope { knots: [Pos {x: 0, y: 0}; L], - tail_visited: HashSet::new(), + tail_visited: HashSet::new() } } @@ -57,7 +58,7 @@ impl Rope { } for i in 1..(self.knots.len()) { - self.move_follower(i); + self.move_follower(i); } self.tail_visited.insert(*self.knots.last().unwrap()); @@ -72,9 +73,9 @@ impl Rope { let dy = leader.y - follower.y; // check to make sure that we didn't do anything wrong previously - if dx.abs() + dy.abs() > 3 - || dx.abs() == 0 && dy.abs() == 3 - || dx.abs() == 3 && dy.abs() == 0 + if dx.abs() + dy.abs() > 4 + || dx.abs() == 0 && dy.abs() > 2 + || dx.abs() > 2 && dy.abs() == 0 { panic!("Invalid head and tail positions: {dx}, {dy}"); } @@ -98,6 +99,43 @@ impl Rope { follower.y += dy; follower.x += dx / 2; } + + // offset by 2 in both dimensions + if dx.abs() == 2 && dy.abs() == 2 { + follower.x += dx / 2; + follower.y += dy / 2; + } + } +} + + +use std::convert::TryFrom; + +impl Display for Rope { + fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { + let min_x = self.knots.iter().map(|pos| pos.x).min().unwrap(); + let max_x = self.knots.iter().map(|pos| pos.x).max().unwrap(); + let min_y = self.knots.iter().map(|pos| pos.y).min().unwrap(); + let max_y = self.knots.iter().map(|pos| pos.y).max().unwrap(); + + let n_rows = usize::try_from(max_y - min_y + 1).unwrap(); + let n_cols = usize::try_from(max_x - min_x + 1).unwrap(); + let mut grid = vec![vec!['.'; n_cols]; n_rows]; + + for (i, kt) in self.knots.iter().enumerate() { + let rel_x = usize::try_from(kt.x - min_x).unwrap(); + let rel_y = usize::try_from(max_y - kt.y).unwrap(); + let tgt = &mut grid[rel_y][rel_x]; + if *tgt == '.' { + *tgt = char::from_digit(i as u32, 10).unwrap(); + } + } + + for row in grid { + write!(f, "{}\n", row.iter().collect::())?; + } + + Ok(()) } } @@ -117,24 +155,30 @@ fn main() -> Result<(), String> { }) .collect::, String>>()?; - let mut rope = Rope::<10>::new(); - for (dir, dist) in instructions { - rope.do_move(dir, dist) + let mut rope1 = Rope::<2>::new(); + for &(dir, dist) in &instructions { + rope1.do_move(dir, dist); } - println!("{}", rope.tail_visited.len()); + println!("Part 1: {}", rope1.tail_visited.len()); + + let mut rope2 = Rope::<10>::new(); + for &(dir, dist) in &instructions { + rope2.do_move(dir, dist); + } + println!("Part 2: {}", rope2.tail_visited.len()); Ok(()) } -// const DATA: &'static str = include_str!("../data/day9.txt"); -const DATA: &'static str = " -R 5 -U 8 -L 8 -D 3 -R 17 -D 10 -L 25 -U 20 -"; +const DATA: &'static str = include_str!("../data/day9.txt"); +// const DATA: &'static str = " +// R 5 +// U 8 +// L 8 +// D 3 +// R 17 +// D 10 +// L 25 +// U 20 +// ";