Implement with Coordinates struct
This commit is contained in:
parent
6acbdc53f1
commit
22f51dc3ab
1 changed files with 102 additions and 23 deletions
121
src/day_three.rs
121
src/day_three.rs
|
@ -1,15 +1,67 @@
|
||||||
|
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)]
|
||||||
|
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<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 {
|
match direction {
|
||||||
"R" => (c.0 + 1, c.1),
|
"R" => Coordinate {
|
||||||
"L" => (c.0 - 1, c.1),
|
step: self.step + 1,
|
||||||
"U" => (c.0, c.1 + 1),
|
x: self.x + 1,
|
||||||
"D" => (c.0, c.1 - 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!"),
|
_ => panic!("Wrong direction format!"),
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn direction_length(entry: String) -> (String, usize) {
|
fn direction_length(entry: String) -> (String, usize) {
|
||||||
|
@ -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]
|
entries[0]
|
||||||
.intersection(&entries[1])
|
.intersection(&entries[1])
|
||||||
.cloned()
|
.cloned()
|
||||||
.map(distance)
|
.map(|c| c.x.abs() + c.y.abs())
|
||||||
|
.collect::<Vec<i32>>()
|
||||||
|
);
|
||||||
|
|
||||||
|
entries[0]
|
||||||
|
.intersection(&entries[1])
|
||||||
|
.cloned()
|
||||||
|
.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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue