From: Grégory Burri Date: Wed, 4 Dec 2019 07:54:44 +0000 (+0100) Subject: Day03 - part 1 X-Git-Url: https://git.euphorik.ch/?a=commitdiff_plain;h=ad906a5049a043bb522252ad02bd9cca7422be44;p=advent_of_code_2019.git Day03 - part 1 --- diff --git a/src/day02.rs b/src/day02.rs index 76bc33e..9db5379 100644 --- a/src/day02.rs +++ b/src/day02.rs @@ -19,8 +19,8 @@ fn execute_op_code(code : &mut [i32]) -> i32 { pub fn find_noun_and_verb(code : &[i32]) -> i32 { loop { - for noun in 0..=99 { - for verb in 0..=99 { + for verb in 0..=99 { + for noun in 0..=99 { let mut code_copy = Vec::from(code); code_copy[1] = noun; code_copy[2] = verb; diff --git a/src/day03.rs b/src/day03.rs new file mode 100644 index 0000000..a35ce3f --- /dev/null +++ b/src/day03.rs @@ -0,0 +1,59 @@ +use std::iter::Iterator; +use std::collections::HashSet; + +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 }, + } + } + pos + } + + let (positions_wire1, positions_wire2) = (positions(wire1), positions(wire2)); + let cross: HashSet<_> = positions_wire1.intersection(&positions_wire2).collect(); + cross.iter().map(|(x, y)| x.abs() + y.abs()).min().unwrap() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn simple_cases() { + assert_eq!( + manhattan_distance_from_cross_to_port( + &split_movements("R8,U5,L5,D3"), + &split_movements("U7,R6,D4,L4") + ), + 6 + ); + + assert_eq!( + manhattan_distance_from_cross_to_port( + &split_movements("R75,D30,R83,U83,L12,D49,R71,U7,L72"), + &split_movements("U62,R66,U55,R34,D71,R55,D58,R83") + ), + 159 + ); + + assert_eq!( + manhattan_distance_from_cross_to_port( + &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") + ), + 135 + ); + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 83918d4..eff33ed 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,10 @@ use std::env; +use std::fs; use std::time::Instant; mod day01; mod day02; +mod day03; mod common; fn day01() -> String { @@ -15,6 +17,15 @@ fn day02() -> String { format!("part1: {}, part2: {}", day02::execute_op_code_with_state_fixed(&mut Vec::from(&code[..])), day02::find_noun_and_verb(&code)) } +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])) + ) +} + fn do_day(days: &[fn() -> String], day: usize) { let now = Instant::now(); println!("Result of day {}: {} (time: {} μs)", day, days[day - 1](), now.elapsed().as_micros()); @@ -25,7 +36,8 @@ fn main() { let days: Vec String> = vec!( day01, - day02 + day02, + day03 ); let args: Vec = env::args().skip(1).collect();