132 lines
3.5 KiB
Rust
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");
|
|
} |