From 772e220f46684e338dcf6aa89a75857708ea8571 Mon Sep 17 00:00:00 2001 From: Acvaxoort Date: Tue, 12 Dec 2023 01:30:21 +0100 Subject: [PATCH] day 11 --- day11/Cargo.lock | 7 +++ day11/Cargo.toml | 8 +++ day11/input.txt | 140 +++++++++++++++++++++++++++++++++++++++++ day11/src/main.rs | 157 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 312 insertions(+) create mode 100644 day11/Cargo.lock create mode 100644 day11/Cargo.toml create mode 100644 day11/input.txt create mode 100644 day11/src/main.rs diff --git a/day11/Cargo.lock b/day11/Cargo.lock new file mode 100644 index 0000000..4ab9be8 --- /dev/null +++ b/day11/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "day11" +version = "0.1.0" diff --git a/day11/Cargo.toml b/day11/Cargo.toml new file mode 100644 index 0000000..8f5b9a5 --- /dev/null +++ b/day11/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "day11" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/day11/input.txt b/day11/input.txt new file mode 100644 index 0000000..4a37aab --- /dev/null +++ b/day11/input.txt @@ -0,0 +1,140 @@ +.........................#.........................#.....................#........#..................#............#...............#......... +............................................................................................................................................ +...................................#......................#................................................................................. +............................................................................................#..........................#.....#.............. +..#............................#..............#...................#........................................#.............................#.. +............................................................................................................................................ +................#.....#..............#.......................................#.................#.....#...................................... +........#.............................................#..................................................................#.................. +..........................................#..................#..........#...............#.........................................#......... +#................................................................................#.............................#..........................#. +............................................................................................................................................ +............#............................................................................................................................... +.......................#.....#.................#..........................#.........................................................#....... +.................................................................................................#.......................................... +...................................#................#..................................#.............................#...................... +....#.....................................................#................................................#................#............#.. +..........#......................................................................#............#............................................. +.....................................................................................................#............#..............#.......... +........................#.........................................#.....#...............................................#................... +..#............................#............................................................................................................ +..............#.........................#...................#.....................................#......#.................................. +............................................................................#......#........................................................ +...........................................................................................................................#................ +...................#.................................................................................#..............#............#.......... +..........................#.......................#........................................#.............................................#.. +...................................................................#........................................................................ +#...............#.....................#.....#.....................................#......................................................... +.................................#.........................................#...........................#.................................... +......#.........................................................................................#...........#..............#................ +..........................................................#............................................................................#.... +....................................................................................................................#..........#............ +.............#......#........................#.............................................................................................. +.......................................#............................#..................#.................................................... +.....................................................#..............................................#....................................... +..#..........................#.................................................#...............#................#........................... +.......#.......#............................................#.....................................................................#......... +.........................................#.....#....................................................................#.....#................. +.......................................................................................................#.................................... +....#...............................................#....................#.........#..............#......................................... +.............................................................................................................#.......................#...... +.....................#........#............................................................................................................. +............................................................#.....#.........................................................#............... +.............#...............................#.........#.................................#.......................#.......................... +........................................................................#......#............................................................ +............................#..........................................................................................#...................# +.#.......#..........#..................#.........................................................................................#.......... +................................#........................................................................................................... +....................................................#...........#......................#........#........................................... +......#.....#............................................................................................................................... +.........................................................#.......................#......................#.............................#..... +.........................................#.................................#.........................................#...................... +...............................................................................................................................#............ +.......................#......................................................................#............................................. +#......#......................#...............#.....#..................#...................................................#................ +................................................................................#.............................#............................. +..................#.......................#..........................................#..............#...............#............#........#. +............................................................................................................................................ +..#.............................#..............................#............................................................................ +.............................................#............#............................................................#.................... +........................................................................................................................................#... +......................................................................#..........................#.....#.....#.............................. +.............#.....#........................................................................................................................ +.....#...............................................#.....................................#.......................#........................ +...........................#....................................#..............................................................#............ +............................................................................................................................................ +............................................................................................................................................ +...................................#..........#..............#......#.................#..........................#........#...............#. +..............#......................................................................................................................#...... +..........................#.............................................#......#............................................................ +.......#...........#.........................................................................#.............................................. +................................#.................#.................................................#.....#.............#................... +.......................#................................#............................#...................................................... +............................................#....................#..................................................#....................... +............................#.............................................................#....................#............................ +...........................................................................#................................................................ +.......#.....#.......................#.....................................................................#................................ +..#......................................................................................................................................... +.....................#.........................................................#...............#............................................ +..........................................#..........#.......#........................#..................................................... +................................#...................................#...............................#.....................#.....#........... +............................................................................#...............#............................................... +.............#.............#..........#...........................................#...............................#......................... +...................................................................................................................................#.....#.. +.#.......#...............................................................................................#.................................. +.........................................#...............#............................#.......................#...............#............. +...........................................................................#............................................#................... +....................#..........#.............#.....................................................#........................................ +......#..................................................................................................................................... +#........................................................................................................................................... +....................................................................#.............#.....................#...........#....................... +..........#......................................#.............#.............#.............................................................. +..........................#.............................#..................................#...................#...............#.........#.. +...................#........................................................................................................................ +...................................#..............................#......................................................................... +#..............#.......................................................#.......#..................#........#................................ +........................................................................................................................#................... +.......#.................#......#......................................................#.....................................#.............. +........................................................#.............................................#..................................... +............................................................................#.....................................#......................... +...............................................................#...................#........#......................................#........ +..................#...............................#..................#......................................#............................... +.....................................#................................................................................#..................... +............#.......................................................................................#....................................... +...........................#..............................................................#............................................#.... +..........................................#................................#................................................................ +.............................................................#................................#.................................#........... +.....................#..............#..............................................................................#........................ +..............................#.....................#.............#...................................#..................................... +................#................................................................#.............................#..........#................. +..........#............................................................................#..................#................................. +...................................................................................................#...........................#.....#...... +............................................................................................................................................ +.....#..............................#.............#.................#....................................................................... +.............................................#...............#...........#..........................................#....................... +.......................#......#.........................#...................................................................#............... +.#........................................................................................#............#............................#....... +..................................#.............................................#................#............#............................. +..........................#.........................#....................................................................................... +.............#......#..........................#.....................................#....................#................................. +............................................................#.............#.........................................#....................... +...........................................#................................................................................................ +..........#..........................#...............................#...............................#............................#......... +............................#..................................#.........................#................................................#. +.............................................................................#...................#.......................................... +....#...............................................#.................................................................................#..... +.................#.....#.......#...............#......................................#...........................#......................... +....................................#......................................................#................................................ +........................................................#........#..............#......................................#.................... +#......#.....#........................................................................................#.....................#......#........ +...................................................#.........#..........#.......................................#........................... +.........................................................................................#.................................................. +...............................................................................................................................#............ +................................................#..........................#....................#........................................... +.........#.........................................................................#...................#.................................... +..........................#........................................#.........................................#.......#...................... +....................................................#...................................#................................................... +............................................#.................#...................................#...........................#............. +.....................#............#......................................................................................................... +.......#....................................................................#...........................#.........................#......#.. +.......................................................#.......................................................#............................ diff --git a/day11/src/main.rs b/day11/src/main.rs new file mode 100644 index 0000000..dd5d2ad --- /dev/null +++ b/day11/src/main.rs @@ -0,0 +1,157 @@ +use std::fs::read_to_string; +use std::iter::zip; +use std::time::Instant; + +fn naive_implementation(input_str: &str) -> (i64, i64) { + let width = input_str.lines().next().unwrap().len(); + let height = input_str.lines().count(); + // These arrays will hold mapping of initial coordinates to coordinates after expansion + // In the initial loop the elements will be 1 for empty and 0 for non-empty + let mut x_mapping: Vec = vec![1; width]; + let mut y_mapping: Vec = vec![1; height]; + // List of tuples of galaxy coordinates + let mut galaxies: Vec::<(i64, i64)> = vec![]; + for (j, line) in input_str.lines().enumerate() { + for (i, c) in line.bytes().enumerate() { + if c == b'#' { + x_mapping[i] = 0; + y_mapping[j] = 0; + galaxies.push((i as i64, j as i64)); + } + } + } + // Convert mappings of 0 and 1 to accumulated coordinate mappings + // mapping1 is for task 1, mapping2 is for task 2, mapping2 is a purely output argument + let accumulate_mappings = + |mapping1: &mut Vec, mapping2: &mut Vec| { + let mut accmulator: i64 = 0; + let mut accmulator2: i64 = 0; + for (x1, x2) in zip(mapping1.iter_mut(), mapping2.iter_mut()) { + accmulator += *x1; + accmulator2 += *x1 * 999999; + *x1 = accmulator; + *x2 = accmulator2; + accmulator += 1; + accmulator2 += 1; + } + }; + // Convert galaxy coordinates using mapping arrays + // Returns a copy becuase we need two different mappings for two tasks + let map_galaxies = + |galaxies: &Vec<(i64, i64)>, x_mapping: &Vec, y_mapping: &Vec| { + galaxies.iter().map(|&(x, y)| (x_mapping[x as usize], y_mapping[y as usize])).collect::>() + }; + // Calculating the distances pairwise + let sum_distances = + |galaxies: &Vec<(i64, i64)>| { + let mut sum1 = 0; + for (i, &(x1, y1)) in galaxies.iter().enumerate() { + for &(x2, y2) in galaxies[i + 1..].iter() { + sum1 += (x2 - x1).abs() + (y2 - y1).abs(); + } + } + sum1 + }; + let mut x_mapping2: Vec = vec![0; width]; + let mut y_mapping2: Vec = vec![0; height]; + accumulate_mappings(&mut x_mapping, &mut x_mapping2); + accumulate_mappings(&mut y_mapping, &mut y_mapping2); + let galaxies_mapped1 = map_galaxies(&galaxies, &x_mapping, &y_mapping); + let galaxies_mapped2 = map_galaxies(&galaxies, &x_mapping2, &y_mapping2); + let sum1 = sum_distances(&galaxies_mapped1); + let sum2 = sum_distances(&galaxies_mapped2); + (sum1, sum2) +} + +fn improved_implementation(input_str: &str) -> (i64, i64) { + let width = input_str.lines().next().unwrap().len(); + let height = input_str.lines().count(); + // These arrays will hold mapping of initial coordinates to coordinates after expansion + // In the initial loop the elements will be 1 for empty and 0 for non-empty + let mut x_mapping: Vec = vec![1; width]; + let mut y_mapping: Vec = vec![1; height]; + // These arrays hold a tupe of row/col index and count of galaxies in that index + // They will be later mapped using mapping arrays + let mut x_counters = (0..width) + .map(|i| (i as i64, 0i64)).collect::>(); + let mut y_counters = (0..height) + .map(|i| (i as i64, 0i64)).collect::>(); + for (j, line) in input_str.lines().enumerate() { + for (i, c) in line.bytes().enumerate() { + if c == b'#' { + x_mapping[i] = 0; + y_mapping[j] = 0; + let (_, count_x) = &mut x_counters[i]; + *count_x += 1; + let (_, count_y) = &mut y_counters[j]; + *count_y += 1; + } + } + } + // Remove empty rows/cols + x_counters.retain(|(_, counter)| *counter > 0); + y_counters.retain(|(_, counter)| *counter > 0); + // Convert mappings of 0 and 1 to accumulated coordinate mappings + // mapping1 is for task 1, mapping2 is for task 2, mapping2 is a purely output argument + let accumulate_mappings = + |mapping1: &mut Vec, mapping2: &mut Vec| { + let mut accmulator: i64 = 0; + let mut accmulator2: i64 = 0; + for (x1, x2) in zip(mapping1.iter_mut(), mapping2.iter_mut()) { + accmulator += *x1; + accmulator2 += *x1 * 999999; + *x1 = accmulator; + *x2 = accmulator2; + accmulator += 1; + accmulator2 += 1; + } + }; + // Convert counter indices using mapping arrays + // Returns a copy becuase we need two different mappings for two tasks + let map_counter_coordinates = + |counters: &Vec<(i64, i64)>, mapping: &Vec| { + counters.iter().map(|&(i, counter)| (mapping[i as usize], counter)).collect::>() + }; + // Sum all distances along one dimension + let sum_distances = + |counters: &Vec<(i64, i64)>| { + let mut sum1 = 0; + for (i, &(pos1, counter1)) in counters.iter().enumerate() { + for &(pos2, counter2) in counters[i + 1..].iter() { + sum1 += (pos2 - pos1) * counter1 * counter2; + } + } + sum1 + }; + let mut x_mapping2: Vec = vec![0; width]; + let mut y_mapping2: Vec = vec![0; height]; + accumulate_mappings(&mut x_mapping, &mut x_mapping2); + accumulate_mappings(&mut y_mapping, &mut y_mapping2); + let x_counters1 = map_counter_coordinates(&x_counters, &x_mapping); + let y_counters1 = map_counter_coordinates(&y_counters, &y_mapping); + let x_counters2 = map_counter_coordinates(&x_counters, &x_mapping2); + let y_counters2 = map_counter_coordinates(&y_counters, &y_mapping2); + let sum1 = sum_distances(&x_counters1) + sum_distances(&y_counters1); + let sum2 = sum_distances(&x_counters2) + sum_distances(&y_counters2); + (sum1, sum2) +} + +fn main() { + let time_start = Instant::now(); + let input_str = read_to_string("input.txt").unwrap(); + let time_start_no_io = Instant::now(); + // Option to + let mut sum1 = 0i64; + let mut sum2 = 0i64; + // Solve multiple times for performance testing + for _ in 0..1000 { + //(sum1, sum2) = naive_implementation(&input_str); + (sum1, sum2) = improved_implementation(&input_str); + } + let elapsed = time_start.elapsed().as_micros(); + let elapsed_no_io = time_start_no_io.elapsed().as_micros(); + println!("Time: {}us", elapsed); + println!("Time without file i/o: {}us", elapsed_no_io); + println!("Sum1: {}", sum1); + println!("Sum1: {}", sum2); +}