solve day 11

This commit is contained in:
nora 2023-12-12 19:46:44 +01:00
parent 5126304fd0
commit 7aa3aa3dfa
3 changed files with 141 additions and 68 deletions

70
2023/day11/src/faster.rs Normal file
View file

@ -0,0 +1,70 @@
use std::cmp::{max, min};
use helper::IteratorExt;
use crate::Universe;
fn height_width(universe: &Universe, count: u64) -> (Vec<u64>, Vec<u64>) {
let rows = universe
.rows
.iter()
.map(|row| if row.iter().all(|b| !b) { count } else { 1 })
.collect_vec();
let cols = (0..universe.rows[0].len())
.map(|col| {
if universe.rows.iter().all(|row| !row[col]) {
count
} else {
1
}
})
.collect_vec();
(rows, cols)
}
fn solve(input: &str, count: u64) -> u64 {
let universe = super::parse(input);
let (row_height, col_width) = height_width(&universe, count);
let galaxies = universe
.rows
.iter()
.enumerate()
.flat_map(|(i, row)| {
row.iter()
.copied()
.enumerate()
.filter(|&(_, b)| b)
.map(move |(j, _)| (i, j))
})
.collect_vec();
let mut sum = 0;
for i in 0..galaxies.len() {
for j in (i + 1)..galaxies.len() {
let lhs = galaxies[i];
let rhs = galaxies[j];
let x_range = min(lhs.1, rhs.1)..max(lhs.1, rhs.1);
let distance_x = x_range.map(|x| col_width[x]).sum::<u64>();
let y_range = min(lhs.0, rhs.0)..max(lhs.0, rhs.0);
let distance_y = y_range.map(|x| row_height[x]).sum::<u64>();
sum += distance_x + distance_y;
}
}
sum as u64
}
pub fn part1(input: &str) -> u64 {
solve(input, 2)
}
pub fn part2(input: &str) -> u64 {
solve(input, 1_000_000)
}

View file

@ -1,3 +1,6 @@
mod faster;
mod p1slow;
use std::fmt::Debug; use std::fmt::Debug;
use helper::{Day, IteratorExt, Variants}; use helper::{Day, IteratorExt, Variants};
@ -11,10 +14,11 @@ struct Day11;
helper::define_variants! { helper::define_variants! {
day => crate::Day11; day => crate::Day11;
part1 { part1 {
basic => crate::part1; basic => crate::p1slow::part1;
faster => crate::faster::part1, sample_count=200;
} }
part2 { part2 {
basic => crate::part2; basic => crate::faster::part2, sample_count=200;
} }
} }
@ -54,78 +58,15 @@ fn parse(input: &str) -> Universe {
} }
} }
fn expand(universe: Universe) -> Universe {
let mut rows = universe
.rows
.into_iter()
.flat_map(|row| {
if row.iter().all(|b| !b) {
vec![row.clone(), row]
} else {
vec![row]
}
})
.collect_vec();
let mut col = 0;
while col < rows[0].len() {
if rows.iter().all(|row| !row[col]) {
rows.iter_mut().for_each(|row| row.insert(col, false));
col += 1;
}
col += 1;
}
Universe { rows }
}
fn part1(input: &str) -> u64 {
let universe = parse(input);
let universe = expand(universe);
let galaxies = universe
.rows
.iter()
.enumerate()
.flat_map(|(i, row)| {
row.iter()
.copied()
.enumerate()
.filter(|&(_, b)| b)
.map(move |(j, _)| (i, j))
})
.collect_vec();
let mut sum = 0;
for i in 0..galaxies.len() {
for j in (i + 1)..galaxies.len() {
let lhs = galaxies[i];
let rhs = galaxies[j];
let distance_x = ((lhs.1 as i64) - (rhs.1 as i64)).abs();
let distance_y = ((lhs.0 as i64) - (rhs.0 as i64)).abs();
sum += distance_x + distance_y;
}
}
sum as u64
}
fn part2(_input: &str) -> u64 {
0
}
helper::tests! { helper::tests! {
day11 Day11; day11 Day11;
part1 { part1 {
small => 374; small => 374;
default => 0; default => 9370588;
} }
part2 { part2 {
small => 0; small => 82000210;
default => 0; default => 746207878188;
} }
} }
helper::benchmarks! {} helper::benchmarks! {}

62
2023/day11/src/p1slow.rs Normal file
View file

@ -0,0 +1,62 @@
use helper::IteratorExt;
use crate::Universe;
fn expand(universe: Universe) -> Universe {
let mut rows = universe
.rows
.into_iter()
.flat_map(|row| {
if row.iter().all(|b| !b) {
vec![row.clone(), row]
} else {
vec![row]
}
})
.collect_vec();
let mut col = 0;
while col < rows[0].len() {
if rows.iter().all(|row| !row[col]) {
rows.iter_mut().for_each(|row| row.insert(col, false));
col += 1;
}
col += 1;
}
Universe { rows }
}
pub fn part1(input: &str) -> u64 {
let universe = super::parse(input);
let universe = expand(universe);
let galaxies = universe
.rows
.iter()
.enumerate()
.flat_map(|(i, row)| {
row.iter()
.copied()
.enumerate()
.filter(|&(_, b)| b)
.map(move |(j, _)| (i, j))
})
.collect_vec();
let mut sum = 0;
for i in 0..galaxies.len() {
for j in (i + 1)..galaxies.len() {
let lhs = galaxies[i];
let rhs = galaxies[j];
let distance_x = ((lhs.1 as i64) - (rhs.1 as i64)).abs();
let distance_y = ((lhs.0 as i64) - (rhs.0 as i64)).abs();
sum += distance_x + distance_y;
}
}
sum as u64
}