1
0
Fork 0

Solve day 11

This commit is contained in:
Lars Martens 2023-12-11 12:58:18 +01:00
parent 0035d5295c
commit c6c6a234c0
Signed by: haselkern
GPG key ID: B5CF1F363C179AD4
2 changed files with 106 additions and 0 deletions

10
input/11-test Normal file
View file

@ -0,0 +1,10 @@
...#......
.......#..
#.........
..........
......#...
.#........
.........#
..........
.......#..
#...#.....

96
src/bin/11.rs Normal file
View file

@ -0,0 +1,96 @@
use aoc2023::*;
use itertools::Itertools;
const INPUT: &str = include_str!("../../input/11");
fn main() {
assert_example!(part1, "11-test", 374);
println!("Part 1: {}", part1(INPUT));
assert_example!(part2, "11-test", 82000210);
println!("Part 2: {}", part2(INPUT));
}
fn part1(input: &str) -> usize {
let mut universe = Universe::parse(input);
universe.expand(2);
universe.sum_of_distances()
}
fn part2(input: &str) -> usize {
let mut universe = Universe::parse(input);
universe.expand(1_000_000);
universe.sum_of_distances()
}
type Galaxy = Vec2<usize>;
struct Universe {
galaxies: Vec<Galaxy>,
}
impl Universe {
fn expand(&mut self, factor: usize) {
let add = factor - 1;
let dimensions = self.dimensions();
// Add additional columns
for x in (0..=dimensions.x).rev() {
let any_galaxies = self.galaxies.iter().any(|g| g.x == x);
if any_galaxies {
continue;
}
self.galaxies
.iter_mut()
.filter(|g| g.x > x)
.for_each(|g| g.x += add);
}
// Add additional rows
for y in (0..=dimensions.y).rev() {
let any_galaxies = self.galaxies.iter().any(|g| g.y == y);
if any_galaxies {
continue;
}
self.galaxies
.iter_mut()
.filter(|g| g.y > y)
.for_each(|g| g.y += add);
}
}
fn dimensions(&self) -> Galaxy {
self.galaxies.iter().fold(Galaxy::default(), |a, b| Galaxy {
x: a.x.max(b.x),
y: a.y.max(b.y),
})
}
fn sum_of_distances(&self) -> usize {
let pairs = self
.galaxies
.iter()
.copied()
.combinations_with_replacement(2)
.map(|list| (list[0], list[1]));
pairs.map(distance).sum()
}
fn parse(input: &str) -> Self {
let galaxies = input.lines().enumerate().flat_map(parse_line).collect();
Self { galaxies }
}
}
fn parse_line((line_index, line): (usize, &str)) -> impl Iterator<Item = Galaxy> + '_ {
line.chars()
.enumerate()
.filter(|&(_x, c)| c == '#')
.map(move |(x, _c)| Vec2::new(x, line_index))
}
/// Taxi cab distance between two galaxies.
fn distance((a, b): (Galaxy, Galaxy)) -> usize {
a.x.abs_diff(b.x) + a.y.abs_diff(b.y)
}