use std::cmp::Ordering::{Equal, Greater, Less}; use crate::utils; pub fn task1() { use self::Bla::*; let input = utils::read_file("input/day06.txt"); let coordinates: Vec<(u16, u16)> = input .lines() .map(|line| { let mut split = line.split(", "); ( split.next().unwrap().parse().unwrap(), split.next().unwrap().parse().unwrap(), ) }) .collect(); let max_x = coordinates.iter().max_by_key(|it| it.0).unwrap().0; let max_y = coordinates.iter().max_by_key(|it| it.1).unwrap().1; let mut area: Vec> = Vec::new(); for _ in 0..max_x { let mut vec = Vec::new(); for _ in 0..max_y { vec.push(Bla::None); } area.push(vec); } for (a, b) in coordinates.iter() { for (x, col) in area.iter_mut().enumerate() { for (y, cell) in col.iter_mut().enumerate() { let d = (i32::abs(*a as i32 - x as i32) + i32::abs(*b as i32 - y as i32)) as u16; *cell = match *cell { None => Single(d, (*a, *b)), Single(dd, (aa, bb)) => match dd.cmp(&d) { Less => Single(dd, (aa, bb)), Equal => Single(d, (*a, *b)), Greater => Multi(d), }, Multi(dd) => { if d < dd { Single(d, (*a, *b)) } else { Multi(dd) } } } } } } let occupation = coordinates .iter() .enumerate() .map(|(_, (a, b))| { let count = area .iter() .flatten() .filter(|entry| { if let Single(_, (x, y)) = entry { a == x && b == y } else { false } }) .count(); let infinite = area[0].iter().any(|bla| bla.belongs_to_point(*a, *b)) || area[area.len() - 1] .iter() .any(|bla| bla.belongs_to_point(*a, *b)) || area.iter().any(|line| line[0].belongs_to_point(*a, *b)) || area .iter() .any(|line| line[line.len() - 1].belongs_to_point(*a, *b)); // println!("{} has size {} (infinite: {:?})", i, count, infinite); (count, infinite) }) .collect::>(); println!( "Overall occupation: {} of {}", occupation.iter().map(|(count, _)| *count).sum::(), area.len() * area[0].len() ); let result = occupation .iter() .filter(|(_, infinite)| !infinite) .max_by_key(|x| x.0); println!("{:?}", result); // 5224 too high } #[derive(Debug)] enum Bla { None, /// distance, node Single(u16, (u16, u16)), /// distance Multi(u16), } impl Bla { fn belongs_to_point(&self, x: u16, y: u16) -> bool { match self { Bla::Single(_, (a, b)) => *a == x && *b == y, _ => false, } } } pub fn task2() { let input = utils::read_file("input/day06.txt"); let coordinates: Vec<(u16, u16)> = input .lines() .map(|line| { let mut split = line.split(", "); ( split.next().unwrap().parse().unwrap(), split.next().unwrap().parse().unwrap(), ) }) .collect(); let max_x = coordinates.iter().max_by_key(|it| it.0).unwrap().0; let max_y = coordinates.iter().max_by_key(|it| it.1).unwrap().1; let result: usize = (0..max_x) .map(|x| { (0..max_y) .map(|y| { coordinates .iter() .map(|(a, b)| { (i32::abs(*a as i32 - x as i32) + i32::abs(*b as i32 - y as i32)) as usize }) .sum::() }) .filter(|it| *it < 10000) .count() }) .sum(); println!("Part 2: {}", result); }