advent-of-code/src/year_2023/day_11_cosmic_expantion/part_one.rs

85 lines
2.0 KiB
Rust

use super::common::{all_false, Galaxy};
pub fn part_one(input_lines: Vec<String>) -> String {
let vert_dim = input_lines.len();
let horz_dim = input_lines[0].len();
let mut matrix = vec![vec![false; horz_dim]; vert_dim];
let mut galaxies: Vec<Galaxy> = Vec::new();
for (y, line) in input_lines.iter().enumerate() {
for (x, c) in line.chars().enumerate() {
matrix[y][x] = c == '#';
}
}
expand_rows(&mut matrix);
expand_cols(&mut matrix);
for x in 0..matrix.len() {
for y in 0..matrix[x].len() {
if matrix[x][y] {
galaxies.push(Galaxy { i: x, j: y });
}
}
}
let mut total_distance = 0;
for i in 0..(galaxies.len() - 1) {
total_distance += distances_from_galaxy(i, &galaxies);
}
total_distance.to_string()
}
fn expand_rows(matrix: &mut Vec<Vec<bool>>) {
let mut i = 0;
while i < matrix.len() {
let row = matrix[i].clone();
if all_false(&row) {
matrix.insert(i, row.clone());
i += 1;
}
i += 1;
}
}
fn expand_cols(matrix: &mut Vec<Vec<bool>>) {
let mut i = 0;
while i < matrix[0].len() {
let col = matrix.iter().map(|row| row[i]).collect::<Vec<bool>>();
if all_false(&col) {
for row in matrix.iter_mut() {
row.insert(i, false);
}
i += 1;
}
i += 1;
}
}
fn distances_from_galaxy(id : usize, galaxies: &Vec<Galaxy>) -> usize {
let mut distance: usize = 0;
for i in (id + 1)..galaxies.len() {
distance += euclidian_distance(galaxies[id].i, galaxies[id].j, galaxies[i].i, galaxies[i].j);
}
distance
}
fn euclidian_distance(x1: usize, y1: usize, x2: usize, y2: usize) -> usize {
let x;
if x1 > x2 {
x = x1 - x2;
} else {
x = x2 - x1;
}
let y;
if y1 > y2 {
y = y1 - y2;
} else {
y = y2 - y1;
}
x + y
}