use regex::Regex; use std::collections::HashMap; use crate::utils; #[derive(PartialEq)] enum Use { Single(u32), Multi, } pub fn task1() { let input = utils::read_file("input/day03.txt"); let re = Regex::new(r"^.(\d+) @ (\d+),(\d+): (\d+)x(\d+)").unwrap(); let count = input .lines() .map(|line| { // #12 @ 590,968: 25x14 let m = re.captures(&line).unwrap(); let id: u32 = m.get(1).unwrap().as_str().parse().unwrap(); let left: u32 = m.get(2).unwrap().as_str().parse().unwrap(); let top: u32 = m.get(3).unwrap().as_str().parse().unwrap(); let width: u32 = m.get(4).unwrap().as_str().parse().unwrap(); let height: u32 = m.get(5).unwrap().as_str().parse().unwrap(); (id, left, top, width, height) }).fold( HashMap::<(u32, u32), Use>::new(), |mut map, (id, left, top, width, height)| { for x in left..left + width { for y in top..top + height { if let None = map.get(&(x, y)) { map.insert((x, y), Use::Single(id)); } else { map.insert((x, y), Use::Multi); } } } map }, ).iter() .filter(|it| *it.1 == Use::Multi) .count(); println!("Part 1: {}", count); } pub fn task2() { let input = utils::read_file("input/day03.txt"); // example entry: #12 @ 590,968: 25x14 let re = Regex::new(r"^.(\d+) @ (\d+),(\d+): (\d+)x(\d+)").unwrap(); let claims: Vec<_> = input .lines() .map(|line| { let m = re.captures(&line).unwrap(); let id: u32 = m.get(1).unwrap().as_str().parse().unwrap(); let left: u32 = m.get(2).unwrap().as_str().parse().unwrap(); let top: u32 = m.get(3).unwrap().as_str().parse().unwrap(); let width: u32 = m.get(4).unwrap().as_str().parse().unwrap(); let height: u32 = m.get(5).unwrap().as_str().parse().unwrap(); (id, left, top, width, height) }).collect(); let distribution: HashMap<(u32, u32), Use> = claims.iter().fold( HashMap::<(u32, u32), Use>::new(), |mut map, (id, left, top, width, height)| { for x in *left..*left + *width { for y in *top..*top + *height { if let None = map.get(&(x, y)) { map.insert((x, y), Use::Single(*id)); } else { map.insert((x, y), Use::Multi); } } } map }, ); let (winner_id, _, _, _, _) = claims .iter() .find(|(_id, left, top, width, height)| { for x in *left..*left + *width { for y in *top..*top + *height { if let Some(Use::Multi) = distribution.get(&(x, y)) { return false; } } } true }).unwrap(); println!("Part 2: {}", winner_id); }