diff --git a/src/tasks/day03.rs b/src/tasks/day03.rs index e684dd4..0413044 100644 --- a/src/tasks/day03.rs +++ b/src/tasks/day03.rs @@ -1,5 +1,6 @@ -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; use std::fs; +use std::iter; #[allow(dead_code)] pub fn run() { @@ -7,6 +8,7 @@ pub fn run() { let p1: Vec<&str> = content.lines().next().unwrap().split(",").collect(); let p2: Vec<&str> = content.lines().skip(1).next().unwrap().split(",").collect(); task1(&p1, &p2); + task2(&p1, &p2); } fn task1(p1: &Vec<&str>, p2: &Vec<&str>) { @@ -17,7 +19,7 @@ fn task1(p1: &Vec<&str>, p2: &Vec<&str>) { .min_by_key(|(a, b)| a.abs() + b.abs()) .unwrap(); println!( - "Closest point is at distance {}", + "Task 1: Closest point is at distance {}", closest_distance.0.abs() + closest_distance.1.abs() ); } @@ -73,3 +75,56 @@ fn visited_points(p: &Vec<&str>) -> HashSet<(i32, i32)> { .flatten() .collect() } + +fn task2(p1: &Vec<&str>, p2: &Vec<&str>) { + let points1 = get_points(&p1); + let points2 = get_points(&p2); + let set1 = points1 + .keys() + .map(|(x, y)| (*x, *y)) + .collect::>(); + let set2 = points2 + .keys() + .map(|(x, y)| (*x, *y)) + .collect::>(); + let p = set1 + .intersection(&set2) + .min_by_key(|p| points1[p] + points2[p]) + .unwrap(); + println!( + "Task 2: shortest is at {:?} with distances {}/{} = {}", + p, + points1[p], + points2[p], + points1[p] + points2[p] + ); + // 20384 is too short +} + +fn get_points(path: &Vec<&str>) -> HashMap<(i32, i32), usize> { + let mut directions = HashMap::new(); + directions.insert('U', (0, 1)); + directions.insert('D', (0, -1)); + directions.insert('L', (-1, 0)); + directions.insert('R', (1, 0)); + path.iter() + .map(|it| { + let direction = it.chars().next().unwrap(); + let number = it[1..].parse::().unwrap(); + iter::repeat(direction).take(number) + }) + .flatten() + .scan((0, 0), |(sx, sy), dir| { + let (dx, dy) = directions[&dir]; + *sx += dx; + *sy += dy; + Some((*sx, *sy)) + }) + .enumerate() + .fold(HashMap::new(), |mut hm, (i, point)| { + if !hm.contains_key(&point) { + hm.insert(point, i + 1); + } + hm + }) +}