diff --git a/src/day_three.rs b/src/day_three.rs index 5b13a59..45a6f4e 100644 --- a/src/day_three.rs +++ b/src/day_three.rs @@ -1,14 +1,66 @@ +use std::cmp::Ordering; use std::collections::BTreeSet; use std::io; use std::iter::{repeat, successors}; -fn next(c: (i32, i32), direction: &str) -> (i32, i32) { - match direction { - "R" => (c.0 + 1, c.1), - "L" => (c.0 - 1, c.1), - "U" => (c.0, c.1 + 1), - "D" => (c.0, c.1 - 1), - _ => panic!("Wrong direction format!"), +#[derive(Clone, Copy, Debug, Eq)] +struct Coordinate { + step: usize, + x: i32, + y: i32, +} + +impl PartialEq for Coordinate { + fn eq(&self, other: &Self) -> bool { + self.x == other.x && self.y == other.y + } +} + +impl Ord for Coordinate { + fn cmp(&self, other: &Self) -> Ordering { + self.x.cmp(&other.x) + } +} + +impl PartialOrd for Coordinate { + fn partial_cmp(&self, other: &Self) -> Option { + self.y.partial_cmp(&other.y) + } +} + +impl Coordinate { + fn new() -> Self { + Self { + step: 0, + x: 0, + y: 0, + } + } + + fn next(self: &Self, direction: &str) -> Coordinate { + match direction { + "R" => Coordinate { + step: self.step + 1, + x: self.x + 1, + y: self.y, + }, + "L" => Coordinate { + step: self.step + 1, + x: self.x - 1, + y: self.y, + }, + "U" => Coordinate { + step: self.step + 1, + x: self.x, + y: self.y + 1, + }, + "D" => Coordinate { + step: self.step + 1, + x: self.x, + y: self.y - 1, + }, + _ => panic!("Wrong direction format!"), + } } } @@ -19,7 +71,7 @@ fn direction_length(entry: String) -> (String, usize) { ) } -fn to_coordinates(entries: Vec) -> BTreeSet<(i32, i32)> { +fn to_coordinates(entries: Vec) -> BTreeSet { let mut wire = BTreeSet::new(); let mut it = entries @@ -29,8 +81,8 @@ fn to_coordinates(entries: Vec) -> BTreeSet<(i32, i32)> { successors( it.next() - .map(|direction| (next((0, 0), direction.as_ref()))), - |c| it.next().map(|direction| (next(*c, direction.as_ref()))), + .map(|direction| (Coordinate::next(&Coordinate::new(), direction.as_ref()))), + |c| it.next().map(|direction| (c.next(direction.as_ref()))), ) .for_each(|c| { wire.insert(c); @@ -39,26 +91,33 @@ fn to_coordinates(entries: Vec) -> BTreeSet<(i32, i32)> { wire } -fn distance(position: (i32, i32)) -> i32 { - position.0.abs() + position.1.abs() -} - fn closest(input: String) -> Option { - let entries: Vec> = input + let entries: Vec> = input .trim() .split("\n") .map(|line| line.split(",").map(String::from).collect()) .map(to_coordinates) .collect(); + println!( + "{:?}", + entries[0] + .intersection(&entries[1]) + .cloned() + .map(|c| c.x.abs() + c.y.abs()) + .collect::>() + ); + entries[0] .intersection(&entries[1]) .cloned() - .map(distance) + .map(|c| c.x.abs() + c.y.abs()) .min() } -fn first(input: String) -> Option {} +fn best(input: String) -> Option { + None +} pub fn main() -> io::Result<()> { let closest = closest(std::include_str!("../day3-input.txt").to_owned()); @@ -69,17 +128,37 @@ pub fn main() -> io::Result<()> { #[test] fn test_coordinates_for_entry() { - let mut expected: BTreeSet<(i32, i32)> = BTreeSet::new(); + let mut expected: BTreeSet = BTreeSet::new(); for i in 1..11 { - expected.insert((i, 0)); + expected.insert(Coordinate { + step: i, + x: i as i32, + y: 0, + }); } assert_eq!(to_coordinates(vec!["R10".to_owned()]), expected); expected = BTreeSet::new(); - expected.insert((1, 0)); - expected.insert((2, 0)); - expected.insert((2, 1)); - expected.insert((2, 2)); + expected.insert(Coordinate { + step: 1, + x: 1, + y: 0, + }); + expected.insert(Coordinate { + step: 2, + x: 2, + y: 0, + }); + expected.insert(Coordinate { + step: 3, + x: 1, + y: 1, + }); + expected.insert(Coordinate { + step: 4, + x: 2, + y: 2, + }); let input = "R2,U2".to_owned().split(",").map(String::from).collect(); assert_eq!(to_coordinates(input), expected); }