|
|
@ -15,14 +15,14 @@ enum Segment { |
|
|
|
} |
|
|
|
|
|
|
|
enum SegmentError { |
|
|
|
UnknowDirection(char), |
|
|
|
UnknownDirection(char), |
|
|
|
ParseIntError(ParseIntError) |
|
|
|
} |
|
|
|
|
|
|
|
impl Display for SegmentError { |
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
|
|
|
match *self { |
|
|
|
SegmentError::UnknowDirection(direction) => write!(f, "Unknow direction `{}`", direction), |
|
|
|
SegmentError::UnknownDirection(direction) => write!(f, "Unknown direction `{}`", direction), |
|
|
|
SegmentError::ParseIntError(ref e) => e.fmt(f), |
|
|
|
} |
|
|
|
} |
|
|
@ -41,7 +41,7 @@ impl FromStr for Segment { |
|
|
|
'R' => Right(length), |
|
|
|
'L' => Left(length), |
|
|
|
direction => { |
|
|
|
return Err(SegmentError::UnknowDirection(direction)); |
|
|
|
return Err(SegmentError::UnknownDirection(direction)); |
|
|
|
} |
|
|
|
}; |
|
|
|
Ok(segment) |
|
|
@ -67,6 +67,11 @@ impl Segment { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
fn parse_input<F: BufRead> (input: &mut F) -> Vec<Segment> { |
|
|
|
let mut buf = String::new(); |
|
|
|
let _num_bytes = input.read_line(&mut buf).expect("Unable to read a line of input file"); |
|
|
|
buf.trim().split(",").filter_map(|segment| segment.parse().ok()).collect() |
|
|
|
} |
|
|
|
|
|
|
|
pub fn part1<F: BufRead> (mut input: F) { |
|
|
|
let path1 = parse_input(&mut input); |
|
|
@ -75,6 +80,16 @@ pub fn part1<F: BufRead> (mut input: F) { |
|
|
|
println!("{}", res); |
|
|
|
} |
|
|
|
|
|
|
|
fn compute_closest_intersection(path1: Vec<Segment>, path2: Vec<Segment>) -> i32 { |
|
|
|
let steps1 = build_full_path(path1, 0, (0, 0), HashMap::new(), 1); |
|
|
|
let steps2 = build_full_path(path2, 0, (0, 0), HashMap::new(), 1); |
|
|
|
|
|
|
|
let seen1: HashSet<_> = steps1.keys().collect(); |
|
|
|
let seen2: HashSet<_> = steps2.keys().collect(); |
|
|
|
|
|
|
|
seen1.intersection(&seen2).map(|(x, y)| x.abs() + y.abs()).min().unwrap() |
|
|
|
} |
|
|
|
|
|
|
|
pub fn part2<F: BufRead> (mut input: F) { |
|
|
|
let path1 = parse_input(&mut input); |
|
|
|
let path2 = parse_input(&mut input); |
|
|
@ -82,12 +97,6 @@ pub fn part2<F: BufRead> (mut input: F) { |
|
|
|
println!("{}", res); |
|
|
|
} |
|
|
|
|
|
|
|
fn parse_input<F: BufRead> (input: &mut F) -> Vec<Segment> { |
|
|
|
let mut buf = String::new(); |
|
|
|
let _num_bytes = input.read_line(&mut buf).expect("Unable to read a line of input file"); |
|
|
|
buf.trim().split(",").filter_map(|segment| segment.parse().ok()).collect() |
|
|
|
} |
|
|
|
|
|
|
|
fn compute_first_intersection(path1: Vec<Segment>, path2: Vec<Segment>) -> i32 { |
|
|
|
let steps1 = build_full_path(path1, 0, (0, 0), HashMap::new(), 1); |
|
|
|
let steps2 = build_full_path(path2, 0, (0, 0), HashMap::new(), 1); |
|
|
@ -98,16 +107,6 @@ fn compute_first_intersection(path1: Vec<Segment>, path2: Vec<Segment>) -> i32 { |
|
|
|
seen1.intersection(&seen2).map(|coord| steps1[coord] + steps2[coord]).min().unwrap() |
|
|
|
} |
|
|
|
|
|
|
|
fn compute_closest_intersection(path1: Vec<Segment>, path2: Vec<Segment>) -> i32 { |
|
|
|
let steps1 = build_full_path(path1, 0, (0, 0), HashMap::new(), 1); |
|
|
|
let steps2 = build_full_path(path2, 0, (0, 0), HashMap::new(), 1); |
|
|
|
|
|
|
|
let seen1: HashSet<_> = steps1.keys().collect(); |
|
|
|
let seen2: HashSet<_> = steps2.keys().collect(); |
|
|
|
|
|
|
|
seen1.intersection(&seen2).map(|(x, y)| x.abs() + y.abs()).min().unwrap() |
|
|
|
} |
|
|
|
|
|
|
|
fn build_full_path( |
|
|
|
path: Vec<Segment>, |
|
|
|
index: usize, |
|
|
|