diff --git a/day9/src/grid.rs b/day9/src/grid.rs deleted file mode 100644 index c71b60c..0000000 --- a/day9/src/grid.rs +++ /dev/null @@ -1,92 +0,0 @@ -/// A virtual 2d grid in an ordinary vector. Taken from day 8's puzzle solving implementation -#[derive(Debug)] -pub struct Grid { - width: usize, - pub vec: Vec, -} - -impl Grid { - pub fn new(width: usize) -> Self { - Grid { - width, - vec: Vec::new(), - } - } - - // Convert x,y coordinate into linear array index - pub fn xy_idx(&self, x: usize, y: usize) -> usize { - (y * self.width) + x - } - - /// Convert linear array index to x,y coordinate - pub fn idx_xy(&self, idx: usize) -> (usize, usize) { - (idx % self.width, idx / self.width) - } - - pub fn get(&self, idx: usize) -> Option<&T> { - self.vec.get(idx) - } - - pub fn get_mut(&mut self, idx: usize) -> Option<&mut T> { - self.vec.get_mut(idx) - } - - pub fn row_first_idx(&self, row: usize) -> usize { - let idx = row * self.width; - - if idx < self.vec.len() { - idx - } else { - self.vec.len() - } - } - - pub fn row_last_idx(&self, row: usize) -> usize { - if (row + 1) > self.num_rows() { - return self.vec.len(); - } - - self.row_first_idx(row + 1) - 1 - } - - pub fn num_rows(&self) -> usize { - self.vec.len() / self.width - } - - pub fn num_cols(&self) -> usize { - self.width - } - - pub fn get_row(&mut self, row_num: usize) -> &mut [T] { - let start = self.row_first_idx(row_num); - let end = self.row_last_idx(row_num); - - &mut self.vec[start..=end] - } - - pub fn get_row_indexes(&self, row_num: usize) -> Vec { - let start = self.row_first_idx(row_num); - let end = self.row_last_idx(row_num); - - (start..=end).collect() - } - - pub fn get_column_indexes(&self, col_num: usize) -> Vec { - let mut indexes = Vec::new(); - - if col_num >= self.num_cols() { - panic!( - "Asked for column {}, there are {} columns", - col_num, - self.num_cols() - ); - } - - for r in 0..self.num_rows() { - let idx = self.width * r + col_num; - indexes.push(idx); - } - - indexes - } -} \ No newline at end of file diff --git a/day9/src/main.rs b/day9/src/main.rs index dd1fc26..0cebe63 100644 --- a/day9/src/main.rs +++ b/day9/src/main.rs @@ -1,11 +1,98 @@ -mod grid; +use std::collections::HashSet; -use grid::Grid; +#[derive(Debug)] +enum Direction { + Up, + Down, + Left, + Right, +} +use Direction::*; + +struct Move { + dir: Direction, + amount: usize, +} + +impl Move { + fn from_line(line: &str) -> Self { + let parts: Vec<&str> = line.split_ascii_whitespace().collect(); + + let dir = match parts[0] { + "U" => Up, + "D" => Down, + "L" => Left, + "R" => Right, + _ => panic!("Invalid direction!"), + }; + let amount = parts[1].parse::().unwrap(); + + Move { dir, amount } + } +} + +#[derive(Debug, Default, Copy, Clone, Eq, Hash, PartialEq)] +struct Location { + x: usize, + y: usize, +} + +impl Location { + fn new(x: usize, y: usize) -> Self { + Location { x, y } + } +} + +// ---------------------------------------------------------------------------- + +#[derive(Debug, Default)] +struct Rope { + head: Location, + tail: Location, + head_visited: HashSet, + tail_visited: HashSet, +} + +impl Rope { + pub fn new() -> Self { + Rope { ..Rope::default() } + } + + pub fn move_head(&mut self, moves: Move) { + let from = self.head; + + for _ in 0..moves.amount { + let mut x = from.x; + let mut y = from.y; + + match moves.dir { + Up => y += 1, + Down => y -= 1, + Left => x -= 1, + Right => x += 1, + } + + let to = Location::new(x, y); + + self.move_tail(to); + self.head = to; + self.head_visited.insert(to); + } + } + + fn move_tail(&mut self, head: Location) {} +} // ---------------------------------------------------------------------------- fn main() { let file_str = include_str!("input.txt"); + let mut rope = Rope::new(); + + file_str + .lines() + .map(Move::from_line) + .for_each(|m| rope.move_head(m)); } #[cfg(test)] @@ -15,4 +102,4 @@ mod tests { fn get_data() -> &'static str { include_str!("test-input.txt") } -} \ No newline at end of file +}