From 7b80c47dfc7c3718fe3dbde9aa09a9ba752ab40c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Gr=C3=A9gory=20Burri?= Date: Thu, 5 Dec 2019 13:07:44 +0100 Subject: [PATCH] Day03 - part2 --- src/day03.rs | 76 +++++++++++++++++++++++++++++++++++++++++----------- src/main.rs | 5 ++-- 2 files changed, 64 insertions(+), 17 deletions(-) diff --git a/src/day03.rs b/src/day03.rs index a35ce3f..808f6f9 100644 --- a/src/day03.rs +++ b/src/day03.rs @@ -1,37 +1,56 @@ use std::iter::Iterator; +use std::iter::FromIterator; use std::collections::HashSet; +use std::collections::HashMap; pub fn split_movements(movements: &str) -> Vec<&str> { movements.split(',').collect() } -pub fn manhattan_distance_from_cross_to_port(wire1: &[&str], wire2: &[&str]) -> i32 { - fn positions(wire: &[&str]) -> HashSet<(i32, i32)> { - let (mut x, mut y) = (0, 0); - let mut pos = HashSet::<(i32, i32)>::new(); - for mov in wire { - let distance = mov[1..].parse::().unwrap(); - match mov.chars().nth(0).unwrap() { - 'U' => { for y2 in y+1 ..= y + distance { pos.insert((x, y2)); } y += distance }, - 'D' => { for y2 in y - distance .. y { pos.insert((x, y2)); } y -= distance }, - 'R' => { for x2 in x+1 ..= x + distance { pos.insert((x2, y)); } x += distance }, - 'L' | _ => { for x2 in x - distance .. x { pos.insert((x2, y)); } x -= distance }, - } +fn positions(wire: &[&str]) -> Vec<(i32, i32)> { + let (mut x, mut y) = (0, 0); + let mut pos = Vec::<(i32, i32)>::new(); + for mov in wire { + let distance = mov[1..].parse::().unwrap(); + match mov.chars().nth(0).unwrap() { + 'U' => { for y2 in y+1 ..= y + distance { pos.push((x, y2)); } y += distance }, + 'D' => { for y2 in (y - distance .. y).rev() { pos.push((x, y2)); } y -= distance }, + 'R' => { for x2 in x+1 ..= x + distance { pos.push((x2, y)); } x += distance }, + 'L' | _ => { for x2 in (x - distance .. x).rev() { pos.push((x2, y)); } x -= distance }, } - pos } + pos +} - let (positions_wire1, positions_wire2) = (positions(wire1), positions(wire2)); +pub fn manhattan_distance_from_cross_to_port(wire1: &[&str], wire2: &[&str]) -> i32 { + let positions_wire1: HashSet<(i32, i32)> = HashSet::from_iter(positions(wire1)); + let positions_wire2: HashSet<(i32, i32)> = HashSet::from_iter(positions(wire2)); let cross: HashSet<_> = positions_wire1.intersection(&positions_wire2).collect(); cross.iter().map(|(x, y)| x.abs() + y.abs()).min().unwrap() } +pub fn first_cross_sum_of_lengths(wire1: &[&str], wire2: &[&str]) -> usize { + let positions_wire1 = positions(wire1); + let positions_wire1_indexed: HashMap<&(i32, i32), usize> = HashMap::from_iter(positions_wire1.iter().enumerate().map(|(i, pos)| (pos, i)).rev()); + + positions(wire2) + .iter().enumerate().filter_map( + |(j, pos2)| { + if let Some (i) = positions_wire1_indexed.get(pos2) { + Some (j + i + 2) + } else { + None + } + } + ).min().unwrap() +} + #[cfg(test)] mod tests { use super::*; #[test] - fn simple_cases() { + fn part1() { assert_eq!( manhattan_distance_from_cross_to_port( &split_movements("R8,U5,L5,D3"), @@ -56,4 +75,31 @@ mod tests { 135 ); } + + #[test] + fn part2() { + assert_eq!( + first_cross_sum_of_lengths( + &split_movements("R8,U5,L5,D3"), + &split_movements("U7,R6,D4,L5") + ), + 30 + ); + + assert_eq!( + first_cross_sum_of_lengths( + &split_movements("R75,D30,R83,U83,L12,D49,R71,U7,L72"), + &split_movements("U62,R66,U55,R34,D71,R55,D58,R83") + ), + 610 + ); + + assert_eq!( + first_cross_sum_of_lengths( + &split_movements("R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51"), + &split_movements("U98,R91,D20,R16,D67,R40,U7,R15,U6,R7") + ), + 410 + ); + } } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index eff33ed..b508728 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,8 +21,9 @@ fn day03() -> String { let file_content = fs::read_to_string("data/day03.input").unwrap(); let movements: Vec<&str> = file_content.lines().collect(); format!( - "part1: {}", - day03::manhattan_distance_from_cross_to_port(&day03::split_movements(&movements[0]), &day03::split_movements(&movements[1])) + "part1: {}, part2: {}", + day03::manhattan_distance_from_cross_to_port(&day03::split_movements(&movements[0]), &day03::split_movements(&movements[1])), + day03::first_cross_sum_of_lengths(&day03::split_movements(&movements[0]), &day03::split_movements(&movements[1])) ) } -- 2.45.2