From a0a3775ff6cb7cce2e4c27a9bc2b36c343a08be7 Mon Sep 17 00:00:00 2001 From: kageru Date: Fri, 13 Dec 2019 13:40:32 +0100 Subject: [PATCH] Refactor grid into separate module --- 2019/11/Cargo.toml | 1 + 2019/11/src/main.rs | 42 +++++++---------------------- 2019/grid/Cargo.toml | 10 +++++++ 2019/grid/src/lib.rs | 64 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 33 deletions(-) create mode 100644 2019/grid/Cargo.toml create mode 100644 2019/grid/src/lib.rs diff --git a/2019/11/Cargo.toml b/2019/11/Cargo.toml index 3695414..f639c71 100644 --- a/2019/11/Cargo.toml +++ b/2019/11/Cargo.toml @@ -9,3 +9,4 @@ edition = "2018" [dependencies] intcode = { path = "../intcode" } itertools = "0.8.2" +grid = { path = "../grid" } diff --git a/2019/11/src/main.rs b/2019/11/src/main.rs index ea9c2f9..dc2b89a 100644 --- a/2019/11/src/main.rs +++ b/2019/11/src/main.rs @@ -1,5 +1,5 @@ use intcode::*; -use itertools::join; +use grid::*; use std::collections::HashMap; enum Direction { @@ -11,8 +11,8 @@ enum Direction { struct Robot { direction: Direction, - position: (i64, i64), - visited: HashMap<(i64, i64), i64>, + position: Position2D, + visited: HashMap, } impl Robot { @@ -37,10 +37,10 @@ impl Robot { fn mv(&mut self) { let pos = self.position; self.position = match self.direction { - Direction::Up => (pos.0, pos.1 + 1), - Direction::Right => (pos.0 + 1, pos.1), - Direction::Left => (pos.0 - 1, pos.1), - Direction::Down => (pos.0, pos.1 - 1), + Direction::Up => pos + (0, 1).into(), + Direction::Right => pos + (1, 0).into(), + Direction::Left => pos + (-1, 0).into(), + Direction::Down => pos + (0, -1).into(), } } @@ -53,19 +53,9 @@ impl Robot { } } -#[rustfmt::skip] -fn get_boundaries(positions: &HashMap<(i64, i64), i64>) -> (i64, i64, i64, i64) { - let keys = positions.keys(); - let x_max = keys.clone().into_iter().max_by_key(|k| k.0).unwrap().0; - let y_max = keys.clone().into_iter().max_by_key(|k| k.1).unwrap().1; - let x_min = keys.clone().into_iter().min_by_key(|k| k.0).unwrap().0; - let y_min = keys.clone().into_iter().min_by_key(|k| k.1).unwrap().1; - (x_min, x_max, y_min, y_max) -} - fn start_with_input(input: Vec, color: i64) -> Robot { let mut robot = Robot { - position: (0, 0), + position: (0, 0).into(), visited: HashMap::new(), direction: Direction::Up, }; @@ -80,25 +70,11 @@ fn start_with_input(input: Vec, color: i64) -> Robot { robot } -fn draw_ascii_text(coordinates: &HashMap<(i64, i64), i64>) -> String { - let (x_min, x_max, y_min, y_max) = get_boundaries(&coordinates); - join( - (y_min..y_max + 1).rev().map(|y| { - (x_min..x_max) - .map(|x| coordinates.get(&(x, y)).unwrap_or(&0).to_string()) - .collect::() - .replace('0', " ") - .replace('1', "█") - }), - "\n", - ) -} - fn main() { let input = read_input(); let part1_robot = start_with_input(input.clone(), 0); println!("Part 1: {}", part1_robot.visited.len()); let part2_robot = start_with_input(input.clone(), 1); - println!("Part 2:\n{}", draw_ascii_text(&part2_robot.visited)); + println!("Part 2:\n{}", draw_ascii(&part2_robot.visited, 0).replace('0', " ").replace('1', "•")); } diff --git a/2019/grid/Cargo.toml b/2019/grid/Cargo.toml new file mode 100644 index 0000000..657637d --- /dev/null +++ b/2019/grid/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "grid" +version = "0.1.0" +authors = ["kageru "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +itertools = "0.8.2" diff --git a/2019/grid/src/lib.rs b/2019/grid/src/lib.rs new file mode 100644 index 0000000..50e1b66 --- /dev/null +++ b/2019/grid/src/lib.rs @@ -0,0 +1,64 @@ +use itertools::join; +use std::collections::HashMap; + +#[derive(Hash, PartialEq, Eq, Debug, Clone, Copy)] +pub struct Position2D { + x: i64, + y: i64, +} + +struct Boundaries { + x_min: i64, + x_max: i64, + y_min: i64, + y_max: i64, +} + +#[rustfmt::skip] +fn get_boundaries(input: &[&Position2D]) -> Boundaries { + let x_min = input.iter().min_by_key(|k| k.x).map(|p| p.x).unwrap_or(0); + let x_max = input.iter().max_by_key(|k| k.x).map(|p| p.x).unwrap_or(0); + let y_min = input.iter().min_by_key(|k| k.y).map(|p| p.y).unwrap_or(0); + let y_max = input.iter().max_by_key(|k| k.y).map(|p| p.y).unwrap_or(0); + Boundaries { x_min, x_max, y_min, y_max } +} + +pub fn draw_ascii(coordinates: &HashMap, default: T) -> String { + let b = get_boundaries(&coordinates.keys().collect::>()); + join( + (b.y_min..=b.y_max).rev().map(|y| { + (b.x_min..b.x_max) + .map(|x| { + coordinates + .get(&(x, y).into()) + .unwrap_or(&default) + .to_string() + }) + .collect::() + }), + "\n", + ) +} + +impl std::ops::Add for Position2D { + type Output = Position2D; + + fn add(self, rhs: Position2D) -> Position2D { + Position2D { + x: self.x + rhs.x, + y: self.y + rhs.y, + } + } +} + +impl From<(i64, i64)> for Position2D { + fn from(tuple: (i64, i64)) -> Position2D { + Position2D { + x: tuple.0, + y: tuple.1, + } + } +} + +#[cfg(test)] +mod tests {}