AoC2021/src/day11.rs

132 lines
3.5 KiB
Rust

use std::collections::HashMap;
use crate::Day;
type FlashMap = HashMap<(i32, i32), i32>;
pub struct Day11(FlashMap);
impl Day for Day11 {
fn init(content: String) -> anyhow::Result<Self> {
let mut map = HashMap::new();
for (y, n) in content.lines().enumerate() {
for (x, char) in n.chars().enumerate() {
map.insert((x as i32, y as i32), char.to_string().parse::<i32>()?);
}
}
Ok(Self(map))
}
fn part1(&self) -> anyhow::Result<String> {
let mut hm = self.0.clone();
let mut flashes = 0;
for _ in 0..100 {
hm.iter_mut().for_each(|(_, x)| *x += 1);
let mut flashing = get_flashes(&hm);
let mut flashed = vec![];
do_flash(&mut hm, &mut flashing, &mut flashed);
let flashing = get_flashes(&hm);
for f in &flashing {
if let Some(entry) = hm.get_mut(f) {
*entry = 0;
}
}
flashes += flashing.len();
}
Ok(format!("{}", flashes))
}
fn part2(&self) -> anyhow::Result<String> {
let mut hm = self.0.clone();
for num in 0..1000 {
hm.iter_mut().for_each(|(_, x)| *x += 1);
let mut flashing = get_flashes(&hm);
let mut flashed = vec![];
do_flash(&mut hm, &mut flashing, &mut flashed);
if flashed.len() == 100 {
return Ok(format!("{}", num + 1));
}
let flashing = get_flashes(&hm);
for f in &flashing {
if let Some(entry) = hm.get_mut(f) {
*entry = 0;
}
}
}
Err(anyhow::Error::msg("It did not flash 100 times :("))
}
}
fn get_flashes(hm: &FlashMap) -> Vec<(i32, i32)> {
hm.iter().filter(|(_, &x)| x > 9).map(|(&p, _)| p).collect::<Vec<_>>()
}
fn do_flash(mut hm: &mut FlashMap, mut flashing: &mut Vec<(i32, i32)>, mut flashed: &mut Vec<(i32, i32)>) {
if let Some((x, y)) = flashing.pop() {
flashed.push((x, y));
for xn in (x - 1)..=(x + 1) {
for yn in (y - 1)..=(y + 1) {
if let Some(e) = hm.get_mut(&(xn, yn)) {
*e += 1;
if *e > 9 && !flashed.contains(&(xn, yn)) && !flashing.contains(&(xn, yn)) {
flashing.push((xn, yn))
}
}
}
}
do_flash(&mut hm, &mut flashing, &mut flashed)
}
}
#[allow(unused)]
fn print_flashes(map: &FlashMap, x_max: i32, y_max: i32) {
let mut v: Vec<Vec<i32>> = Vec::new();
for y in 0..y_max {
let mut col = Vec::new();
for x in 0..x_max {
col.push(*map.get(&(x, y)).unwrap());
}
v.push(col);
}
for line in v {
for ch in line {
print!("{}", ch)
}
println!()
}
println!()
}
#[cfg(test)]
mod tests {
use crate::{Day, day_tests};
use crate::day11::Day11;
const INPUT: &str = r"5483143223
2745854711
5264556173
6141336146
6357385478
4167524645
2176841721
6882881134
4846848554
5283751526";
#[test]
fn part1_test() -> anyhow::Result<()> {
let d = Day11::init(INPUT.to_string())?;
assert_eq!("1656", d.part1()?);
Ok(())
}
#[test]
fn part2_test() -> anyhow::Result<()> {
let d = Day11::init(INPUT.to_string())?;
assert_eq!("195", d.part2()?);
Ok(())
}
day_tests!(Day11, "11", "1647", "348");
}