day11 solution
parent
e7a3ec0ea1
commit
a985a81d6d
|
@ -0,0 +1,177 @@
|
||||||
|
use aoc_runner_derive::aoc;
|
||||||
|
|
||||||
|
struct Galaxy(Vec<Coord>);
|
||||||
|
|
||||||
|
impl Galaxy {
|
||||||
|
fn galaxy_pairs(&self) -> Vec<(Coord, Coord)> {
|
||||||
|
let mut result: Vec<(Coord, Coord)> = vec![];
|
||||||
|
for i in 0..self.0.len() {
|
||||||
|
let one = &self.0[i];
|
||||||
|
for j in i..self.0.len() {
|
||||||
|
if i == j {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let two = &self.0[j];
|
||||||
|
result.push((*one, *two));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sum_shortest_paths(&self) -> usize {
|
||||||
|
let mut result: usize = 0;
|
||||||
|
for (src, dest) in self.galaxy_pairs().iter() {
|
||||||
|
result += src.path_len(&dest);
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
|
||||||
|
struct Coord(usize, usize);
|
||||||
|
|
||||||
|
impl Coord {
|
||||||
|
fn hdist(&self, other: &Self) -> usize {
|
||||||
|
((self.0 as i64) - (other.0 as i64))
|
||||||
|
.abs()
|
||||||
|
.try_into()
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn vdist(&self, other: &Self) -> usize {
|
||||||
|
((self.1 as i64) - (other.1 as i64))
|
||||||
|
.abs()
|
||||||
|
.try_into()
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn path_len(&self, other: &Self) -> usize {
|
||||||
|
self.hdist(other) + self.vdist(other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse(input: &str, empty_space: usize) -> Galaxy {
|
||||||
|
let mut map = [[false; 141]; 141];
|
||||||
|
let mut galaxies: Vec<Coord> = vec![];
|
||||||
|
let mut row: usize = 0;
|
||||||
|
for line in input.lines() {
|
||||||
|
if !line.is_empty() {
|
||||||
|
let mut col = 0;
|
||||||
|
for cur in line.split("") {
|
||||||
|
if cur.is_empty() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if cur != "." {
|
||||||
|
map[row][col] = true;
|
||||||
|
}
|
||||||
|
col += 1;
|
||||||
|
}
|
||||||
|
row += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut empty_rows: Vec<usize> = vec![];
|
||||||
|
let mut empty_cols: Vec<usize> = vec![];
|
||||||
|
for i in 0..141 {
|
||||||
|
let mut found_row = false;
|
||||||
|
let mut found_col = false;
|
||||||
|
for j in 0..141 {
|
||||||
|
if map[i][j] {
|
||||||
|
found_row = true;
|
||||||
|
}
|
||||||
|
if map[j][i] {
|
||||||
|
found_col = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found_row {
|
||||||
|
empty_rows.push(i);
|
||||||
|
}
|
||||||
|
if !found_col {
|
||||||
|
empty_cols.push(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut prior_rows: Vec<usize> = vec![];
|
||||||
|
let mut prior_cols: Vec<usize> = vec![];
|
||||||
|
for row in 0..141 {
|
||||||
|
prior_rows.push(
|
||||||
|
empty_rows
|
||||||
|
.iter()
|
||||||
|
.filter(|t| **t < row)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.len(),
|
||||||
|
);
|
||||||
|
for col in 0..141 {
|
||||||
|
if row == 0 {
|
||||||
|
prior_cols.push(
|
||||||
|
empty_cols
|
||||||
|
.iter()
|
||||||
|
.filter(|t| **t < col)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.len(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if !map[row][col] {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let calcrow = row + prior_rows[row] * empty_space;
|
||||||
|
let calccol = col + prior_cols[col] * empty_space;
|
||||||
|
galaxies.push(Coord(calcrow, calccol));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Galaxy(galaxies)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day11, part1)]
|
||||||
|
fn part1(input: &str) -> usize {
|
||||||
|
parse(&input, 1).sum_shortest_paths()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day11, part2)]
|
||||||
|
fn part2(input: &str) -> usize {
|
||||||
|
parse(&input, 999999).sum_shortest_paths()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
const SAMPLE_DATA: &'static str = r#"...#......
|
||||||
|
.......#..
|
||||||
|
#.........
|
||||||
|
..........
|
||||||
|
......#...
|
||||||
|
.#........
|
||||||
|
.........#
|
||||||
|
..........
|
||||||
|
.......#..
|
||||||
|
#...#.....
|
||||||
|
"#;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sample_data() {
|
||||||
|
let input = parse(&SAMPLE_DATA, 1);
|
||||||
|
assert_eq!(input.0.len(), 9);
|
||||||
|
assert_eq!(input.galaxy_pairs().len(), 36);
|
||||||
|
assert_eq!(input.0[4].path_len(&input.0[8]), 9);
|
||||||
|
assert_eq!(input.0[0].path_len(&input.0[6]), 15);
|
||||||
|
assert_eq!(input.0[2].path_len(&input.0[5]), 17);
|
||||||
|
assert_eq!(input.0[7].path_len(&input.0[8]), 5);
|
||||||
|
assert_eq!(input.sum_shortest_paths(), 374);
|
||||||
|
assert_eq!(part1(&SAMPLE_DATA), 374);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn shortest_path() {
|
||||||
|
let src: Coord = Coord(6, 1);
|
||||||
|
let dest: Coord = Coord(11, 5);
|
||||||
|
assert_eq!(src.path_len(&dest), 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2() {
|
||||||
|
assert_eq!(parse(&SAMPLE_DATA, 9).sum_shortest_paths(), 1030);
|
||||||
|
assert_eq!(parse(&SAMPLE_DATA, 99).sum_shortest_paths(), 8410);
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,5 +10,6 @@ mod day07;
|
||||||
mod day08;
|
mod day08;
|
||||||
mod day09;
|
mod day09;
|
||||||
mod day10;
|
mod day10;
|
||||||
|
mod day11;
|
||||||
|
|
||||||
aoc_lib! { year = 2023 }
|
aoc_lib! { year = 2023 }
|
||||||
|
|
Loading…
Reference in New Issue