advent-of-code-2021/day11/src/main.rs

90 lines
2.2 KiB
Rust
Raw Normal View History

use std::{fs, env, vec};
fn read_input(path: &str) -> String {
return fs::read_to_string(path).expect("Cannot read file.");
}
fn parse_input(s: &str) -> Vec<Vec<u32>> {
return s.lines()
.map(|l| l.chars().filter_map(|e| e.to_digit(10)).collect())
.collect();
}
fn compute_octopus(v: &mut Vec<Vec<u32>>, l: usize, c: usize, f: &mut Vec<(usize, usize)>) {
v[l][c] += 1;
if v[l][c] > 9 && !f.contains(&(l, c)) {
f.push((l, c));
flash_around(v, l, c, f);
}
}
fn flash_around(v: &mut Vec<Vec<u32>>, l: usize, c: usize, f: &mut Vec<(usize, usize)>) {
for i in (l as i32 - 1)..=(l as i32 + 1) {
for j in (c as i32 - 1)..=(c as i32 + 1) {
let x = i as usize;
let y = j as usize;
if i >= 0 && x < v.len()
&& j >= 0 && y < v[x].len() {
compute_octopus(v, x, y, f);
}
}
}
}
fn apply_one_day(v: &mut Vec<Vec<u32>>) -> u32 {
let mut f = vec![];
for l in 0..v.len() {
for c in 0..v[l].len() {
compute_octopus(v, l, c, &mut f);
}
}
for l in 0..v.len() {
for c in 0..v[l].len() {
if v[l][c] > 9 {
v[l][c] = 0;
}
}
}
return f.len() as u32;
}
fn apply_x_days(mut v: Vec<Vec<u32>>, x: u32) -> u32 {
let mut n = 0;
for _i in 0..x {
n += apply_one_day(&mut v);
}
return n;
}
fn is_uniform(v: &Vec<Vec<u32>>) -> bool {
if v.is_empty() || v[0].is_empty() { return true; }
let x = v[0][0];
for l in v {
for i in l {
if *i != x { return false; }
}
}
return true;
}
fn apply_while_not_synced(mut v: Vec<Vec<u32>>) -> u32 {
let mut i = 0;
while !is_uniform(&v) {
apply_one_day(&mut v);
i += 1;
}
return i;
}
fn main() {
let args: Vec<String> = env::args().collect();
for arg in args.iter().skip(1) {
let input = read_input(&arg);
let vec_in = parse_input(&input);
println!("[{}]", &arg);
println!("\t[Part 1] => Answer is '{}'.", apply_x_days(vec_in.clone(), 100));
println!("\t[Part 2] => Answer is '{}'.", apply_while_not_synced(vec_in));
}
}