Refactor to struct and enumerate steps
This commit is contained in:
parent
6acbdc53f1
commit
9d1d057e09
1 changed files with 76 additions and 40 deletions
116
src/day_three.rs
116
src/day_three.rs
|
@ -1,50 +1,60 @@
|
|||
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) {
|
||||
#[derive(Copy, Clone, Eq, Debug)]
|
||||
struct Coord(usize, (i32, i32));
|
||||
|
||||
impl PartialEq for Coord {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.1 == other.1
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for Coord {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
(self.1).cmp(&(other.1))
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for Coord {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
self.1.partial_cmp(&other.1)
|
||||
}
|
||||
}
|
||||
|
||||
fn next(c: (i32, i32), direction: char) -> (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),
|
||||
'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!"),
|
||||
}
|
||||
}
|
||||
|
||||
fn direction_length(entry: String) -> (String, usize) {
|
||||
(
|
||||
entry.chars().nth(0).unwrap().to_string(),
|
||||
entry[1..].parse().unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
fn to_coordinates(entries: Vec<String>) -> BTreeSet<(i32, i32)> {
|
||||
fn to_coordinates(entries: Vec<String>) -> BTreeSet<Coord> {
|
||||
let mut wire = BTreeSet::new();
|
||||
|
||||
let mut it = entries
|
||||
.into_iter()
|
||||
.map(direction_length)
|
||||
.map(|entry| (entry.chars().nth(0).unwrap(), entry[1..].parse().unwrap()))
|
||||
.flat_map(|(direction, length)| repeat(direction).take(length));
|
||||
|
||||
successors(
|
||||
it.next()
|
||||
.map(|direction| (next((0, 0), direction.as_ref()))),
|
||||
|c| it.next().map(|direction| (next(*c, direction.as_ref()))),
|
||||
)
|
||||
successors(it.next().map(|direction| (next((0, 0), direction))), |c| {
|
||||
it.next().map(|direction| (next(*c, direction)))
|
||||
})
|
||||
.enumerate()
|
||||
.for_each(|c| {
|
||||
wire.insert(c);
|
||||
wire.insert(Coord(c.0 + 1, c.1));
|
||||
});
|
||||
|
||||
wire
|
||||
}
|
||||
|
||||
fn distance(position: (i32, i32)) -> i32 {
|
||||
position.0.abs() + position.1.abs()
|
||||
}
|
||||
|
||||
fn closest(input: String) -> Option<i32> {
|
||||
let entries: Vec<BTreeSet<(i32, i32)>> = input
|
||||
fn closest(input: &str) -> Option<i32> {
|
||||
let entries: Vec<BTreeSet<Coord>> = input
|
||||
.trim()
|
||||
.split("\n")
|
||||
.map(|line| line.split(",").map(String::from).collect())
|
||||
|
@ -54,32 +64,50 @@ fn closest(input: String) -> Option<i32> {
|
|||
entries[0]
|
||||
.intersection(&entries[1])
|
||||
.cloned()
|
||||
.map(distance)
|
||||
.map(|c| (c.1).0.abs() + (c.1).1.abs())
|
||||
.min()
|
||||
}
|
||||
|
||||
fn first(input: String) -> Option<i32> {}
|
||||
fn first(input: &str) -> Option<i32> {
|
||||
let entries: Vec<BTreeSet<Coord>> = input
|
||||
.trim()
|
||||
.split("\n")
|
||||
.map(|line| line.split(",").map(String::from).collect())
|
||||
.map(to_coordinates)
|
||||
.collect();
|
||||
|
||||
entries[0]
|
||||
.intersection(&entries[1])
|
||||
.cloned()
|
||||
.map(|c| {
|
||||
let other = entries[1].get(&c);
|
||||
println!("{:?}", (c, other));
|
||||
(c.0 + other.unwrap().0) as i32
|
||||
})
|
||||
.min()
|
||||
}
|
||||
|
||||
pub fn main() -> io::Result<()> {
|
||||
let closest = closest(std::include_str!("../day3-input.txt").to_owned());
|
||||
println!("{:?}", closest);
|
||||
let input = std::include_str!("../day3-input.txt");
|
||||
println!("{:?}", closest(input));
|
||||
println!("{:?}", first(input));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_coordinates_for_entry() {
|
||||
let mut expected: BTreeSet<(i32, i32)> = BTreeSet::new();
|
||||
let mut expected: BTreeSet<Coord> = BTreeSet::new();
|
||||
for i in 1..11 {
|
||||
expected.insert((i, 0));
|
||||
expected.insert(Coord(i - 1, (i as i32, 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(Coord(0, (1, 0)));
|
||||
expected.insert(Coord(1, (2, 0)));
|
||||
expected.insert(Coord(2, (2, 1)));
|
||||
expected.insert(Coord(3, (2, 2)));
|
||||
let input = "R2,U2".to_owned().split(",").map(String::from).collect();
|
||||
assert_eq!(to_coordinates(input), expected);
|
||||
}
|
||||
|
@ -87,11 +115,19 @@ fn test_coordinates_for_entry() {
|
|||
#[test]
|
||||
fn test_part_one() {
|
||||
let input = "R75,D30,R83,U83,L12,D49,R71,U7,L72\n\
|
||||
U62,R66,U55,R34,D71,R55,D58,R83"
|
||||
.to_owned();
|
||||
U62,R66,U55,R34,D71,R55,D58,R83";
|
||||
assert_eq!(closest(input), Some(159));
|
||||
let input = "R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51\n\
|
||||
U98,R91,D20,R16,D67,R40,U7,R15,U6,R7"
|
||||
.to_owned();
|
||||
U98,R91,D20,R16,D67,R40,U7,R15,U6,R7";
|
||||
assert_eq!(closest(input), Some(135));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part_two() {
|
||||
let input = "R75,D30,R83,U83,L12,D49,R71,U7,L72\n\
|
||||
U62,R66,U55,R34,D71,R55,D58,R83";
|
||||
assert_eq!(first(input), Some(610));
|
||||
let input = "R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51\n\
|
||||
U98,R91,D20,R16,D67,R40,U7,R15,U6,R7";
|
||||
assert_eq!(first(input), Some(464));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue