90 lines
2.2 KiB
Rust
90 lines
2.2 KiB
Rust
|
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));
|
||
|
}
|
||
|
}
|
||
|
|