Implement with Coordinates struct

This commit is contained in:
Vladan Popovic 2019-12-15 22:12:21 +01:00
parent 6acbdc53f1
commit 22f51dc3ab
1 changed files with 102 additions and 23 deletions

View File

@ -1,14 +1,66 @@
use std::cmp::Ordering;
use std::collections::BTreeSet; use std::collections::BTreeSet;
use std::io; use std::io;
use std::iter::{repeat, successors}; use std::iter::{repeat, successors};
fn next(c: (i32, i32), direction: &str) -> (i32, i32) { #[derive(Clone, Copy, Debug, Eq)]
match direction { struct Coordinate {
"R" => (c.0 + 1, c.1), step: usize,
"L" => (c.0 - 1, c.1), x: i32,
"U" => (c.0, c.1 + 1), y: i32,
"D" => (c.0, c.1 - 1), }
_ => panic!("Wrong direction format!"),
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<Ordering> {
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<String>) -> BTreeSet<(i32, i32)> { fn to_coordinates(entries: Vec<String>) -> BTreeSet<Coordinate> {
let mut wire = BTreeSet::new(); let mut wire = BTreeSet::new();
let mut it = entries let mut it = entries
@ -29,8 +81,8 @@ fn to_coordinates(entries: Vec<String>) -> BTreeSet<(i32, i32)> {
successors( successors(
it.next() it.next()
.map(|direction| (next((0, 0), direction.as_ref()))), .map(|direction| (Coordinate::next(&Coordinate::new(), direction.as_ref()))),
|c| it.next().map(|direction| (next(*c, direction.as_ref()))), |c| it.next().map(|direction| (c.next(direction.as_ref()))),
) )
.for_each(|c| { .for_each(|c| {
wire.insert(c); wire.insert(c);
@ -39,26 +91,33 @@ fn to_coordinates(entries: Vec<String>) -> BTreeSet<(i32, i32)> {
wire wire
} }
fn distance(position: (i32, i32)) -> i32 {
position.0.abs() + position.1.abs()
}
fn closest(input: String) -> Option<i32> { fn closest(input: String) -> Option<i32> {
let entries: Vec<BTreeSet<(i32, i32)>> = input let entries: Vec<BTreeSet<Coordinate>> = input
.trim() .trim()
.split("\n") .split("\n")
.map(|line| line.split(",").map(String::from).collect()) .map(|line| line.split(",").map(String::from).collect())
.map(to_coordinates) .map(to_coordinates)
.collect(); .collect();
println!(
"{:?}",
entries[0]
.intersection(&entries[1])
.cloned()
.map(|c| c.x.abs() + c.y.abs())
.collect::<Vec<i32>>()
);
entries[0] entries[0]
.intersection(&entries[1]) .intersection(&entries[1])
.cloned() .cloned()
.map(distance) .map(|c| c.x.abs() + c.y.abs())
.min() .min()
} }
fn first(input: String) -> Option<i32> {} fn best(input: String) -> Option<i32> {
None
}
pub fn main() -> io::Result<()> { pub fn main() -> io::Result<()> {
let closest = closest(std::include_str!("../day3-input.txt").to_owned()); let closest = closest(std::include_str!("../day3-input.txt").to_owned());
@ -69,17 +128,37 @@ pub fn main() -> io::Result<()> {
#[test] #[test]
fn test_coordinates_for_entry() { fn test_coordinates_for_entry() {
let mut expected: BTreeSet<(i32, i32)> = BTreeSet::new(); let mut expected: BTreeSet<Coordinate> = BTreeSet::new();
for i in 1..11 { 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); assert_eq!(to_coordinates(vec!["R10".to_owned()]), expected);
expected = BTreeSet::new(); expected = BTreeSet::new();
expected.insert((1, 0)); expected.insert(Coordinate {
expected.insert((2, 0)); step: 1,
expected.insert((2, 1)); x: 1,
expected.insert((2, 2)); 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(); let input = "R2,U2".to_owned().split(",").map(String::from).collect();
assert_eq!(to_coordinates(input), expected); assert_eq!(to_coordinates(input), expected);
} }