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 day09;
|
||||
mod day10;
|
||||
mod day11;
|
||||
|
||||
aoc_lib! { year = 2023 }
|
||||
|
|
Loading…
Reference in New Issue