Refactor to struct and enumerate steps
This commit is contained in:
parent
6acbdc53f1
commit
7e4a7641ff
1 changed files with 75 additions and 40 deletions
115
src/day_three.rs
115
src/day_three.rs
|
@ -1,50 +1,60 @@
|
||||||
|
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(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 {
|
match direction {
|
||||||
"R" => (c.0 + 1, c.1),
|
'R' => (c.0 + 1, c.1),
|
||||||
"L" => (c.0 - 1, c.1),
|
'L' => (c.0 - 1, c.1),
|
||||||
"U" => (c.0, c.1 + 1),
|
'U' => (c.0, c.1 + 1),
|
||||||
"D" => (c.0, c.1 - 1),
|
'D' => (c.0, c.1 - 1),
|
||||||
_ => panic!("Wrong direction format!"),
|
_ => panic!("Wrong direction format!"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn direction_length(entry: String) -> (String, usize) {
|
fn to_coordinates(entries: Vec<String>) -> BTreeSet<Coord> {
|
||||||
(
|
|
||||||
entry.chars().nth(0).unwrap().to_string(),
|
|
||||||
entry[1..].parse().unwrap(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_coordinates(entries: Vec<String>) -> BTreeSet<(i32, i32)> {
|
|
||||||
let mut wire = BTreeSet::new();
|
let mut wire = BTreeSet::new();
|
||||||
|
|
||||||
let mut it = entries
|
let mut it = entries
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(direction_length)
|
.map(|entry| (entry.chars().nth(0).unwrap(), entry[1..].parse().unwrap()))
|
||||||
.flat_map(|(direction, length)| repeat(direction).take(length));
|
.flat_map(|(direction, length)| repeat(direction).take(length));
|
||||||
|
|
||||||
successors(
|
successors(it.next().map(|direction| (next((0, 0), direction))), |c| {
|
||||||
it.next()
|
it.next().map(|direction| (next(*c, direction)))
|
||||||
.map(|direction| (next((0, 0), direction.as_ref()))),
|
})
|
||||||
|c| it.next().map(|direction| (next(*c, direction.as_ref()))),
|
.enumerate()
|
||||||
)
|
|
||||||
.for_each(|c| {
|
.for_each(|c| {
|
||||||
wire.insert(c);
|
wire.insert(Coord(c.0 + 1, c.1));
|
||||||
});
|
});
|
||||||
|
|
||||||
wire
|
wire
|
||||||
}
|
}
|
||||||
|
|
||||||
fn distance(position: (i32, i32)) -> i32 {
|
fn closest(input: &str) -> Option<i32> {
|
||||||
position.0.abs() + position.1.abs()
|
let entries: Vec<BTreeSet<Coord>> = input
|
||||||
}
|
|
||||||
|
|
||||||
fn closest(input: String) -> Option<i32> {
|
|
||||||
let entries: Vec<BTreeSet<(i32, i32)>> = input
|
|
||||||
.trim()
|
.trim()
|
||||||
.split("\n")
|
.split("\n")
|
||||||
.map(|line| line.split(",").map(String::from).collect())
|
.map(|line| line.split(",").map(String::from).collect())
|
||||||
|
@ -54,32 +64,49 @@ fn closest(input: String) -> Option<i32> {
|
||||||
entries[0]
|
entries[0]
|
||||||
.intersection(&entries[1])
|
.intersection(&entries[1])
|
||||||
.cloned()
|
.cloned()
|
||||||
.map(distance)
|
.map(|c| (c.1).0.abs() + (c.1).1.abs())
|
||||||
.min()
|
.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);
|
||||||
|
(c.0 + other.unwrap().0) as i32
|
||||||
|
})
|
||||||
|
.min()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn main() -> io::Result<()> {
|
pub fn main() -> io::Result<()> {
|
||||||
let closest = closest(std::include_str!("../day3-input.txt").to_owned());
|
let input = std::include_str!("../day3-input.txt");
|
||||||
println!("{:?}", closest);
|
println!("{:?}", closest(input));
|
||||||
|
println!("{:?}", first(input));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_coordinates_for_entry() {
|
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 {
|
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);
|
assert_eq!(to_coordinates(vec!["R10".to_owned()]), expected);
|
||||||
|
|
||||||
expected = BTreeSet::new();
|
expected = BTreeSet::new();
|
||||||
expected.insert((1, 0));
|
expected.insert(Coord(0, (1, 0)));
|
||||||
expected.insert((2, 0));
|
expected.insert(Coord(1, (2, 0)));
|
||||||
expected.insert((2, 1));
|
expected.insert(Coord(2, (2, 1)));
|
||||||
expected.insert((2, 2));
|
expected.insert(Coord(3, (2, 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);
|
||||||
}
|
}
|
||||||
|
@ -87,11 +114,19 @@ fn test_coordinates_for_entry() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_part_one() {
|
fn test_part_one() {
|
||||||
let input = "R75,D30,R83,U83,L12,D49,R71,U7,L72\n\
|
let input = "R75,D30,R83,U83,L12,D49,R71,U7,L72\n\
|
||||||
U62,R66,U55,R34,D71,R55,D58,R83"
|
U62,R66,U55,R34,D71,R55,D58,R83";
|
||||||
.to_owned();
|
|
||||||
assert_eq!(closest(input), Some(159));
|
assert_eq!(closest(input), Some(159));
|
||||||
let input = "R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51\n\
|
let input = "R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51\n\
|
||||||
U98,R91,D20,R16,D67,R40,U7,R15,U6,R7"
|
U98,R91,D20,R16,D67,R40,U7,R15,U6,R7";
|
||||||
.to_owned();
|
|
||||||
assert_eq!(closest(input), Some(135));
|
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