From 64e22194d39d2914db1e3bf93c90de9e0791d9b3 Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Fri, 1 Dec 2023 09:21:16 +0100 Subject: chore: reorganize project structure --- 2021/day05/src/main.rs | 136 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 2021/day05/src/main.rs (limited to '2021/day05/src/main.rs') diff --git a/2021/day05/src/main.rs b/2021/day05/src/main.rs new file mode 100644 index 0000000..e55b244 --- /dev/null +++ b/2021/day05/src/main.rs @@ -0,0 +1,136 @@ +use std::fs; +use std::path::Path; +use regex::Regex; +use lazy_static::lazy_static; + +#[derive(Debug,PartialEq)] +struct Segment(u32,u32,u32,u32); + +impl Segment { + fn is_hor(&self) -> bool { + self.1 == self.3 + } + fn is_ver(&self) -> bool { + self.0 == self.2 + } +} + +/* AOC21 Day 7: https://adventofcode.com/2021/day/7 */ +fn main() { + let input = Path::new("resources").join("input.txt"); + let content = fs::read_to_string(input).expect("Unable to read input file"); + let (size, segments) = parse_input(&content); + let area = radar(&segments, size, false); + println!("Ex1: The result is: {}", area.iter().filter(|&&c| c > 1).count()); + let area = radar(&segments, size, true); + println!("Ex2: The result is: {}", area.iter().filter(|&&c| c > 1).count()); +} + +fn radar(segments: &[Segment], size: u32, diagonals: bool) -> Vec { + let mut area = vec![0;(size+1).pow(2) as usize]; + segments.iter().for_each( + |s| match s { + s if s.is_hor() => { + range(s.0, s.2).iter().for_each(|x| area[((size+1)*s.1 + x) as usize] += 1) + }, + s if s.is_ver() => { + range(s.1, s.3).iter().for_each(|y| area[((size+1)*y + s.0) as usize] += 1) + }, + s => { + if diagonals { + range(s.0,s.2).iter().zip(range(s.1,s.3)).for_each(|(x,y)| area[((size+1)*y + x) as usize] += 1) + } + } + } + ); + area +} + +fn parse_input(s: &str) -> (u32, Vec) { + lazy_static! { + static ref RE: Regex = Regex::new(r"^(\d+),(\d+) -> (\d+),(\d+)$").unwrap(); + } + let mut max = 0; + let segs = s.lines().map(|l| { + let caps = RE.captures(l).expect("Malformed input"); + let x1 = caps.get(1).unwrap().as_str().parse().expect("Malformed input"); + let y1 = caps.get(2).unwrap().as_str().parse().expect("Malformed input"); + let x2 = caps.get(3).unwrap().as_str().parse().expect("Malformed input"); + let y2 = caps.get(4).unwrap().as_str().parse().expect("Malformed input"); + max = *[x1, x2, y1, y2, max].iter().max().unwrap(); + Segment(x1, y1, x2, y2) + }).collect(); + (max, segs) +} + +fn range(from: u32, to: u32) -> Vec { + if from < to { + (from..=to).collect() + } else { + (to..=from).rev().collect() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + const INPUT: &str = "0,9 -> 5,9 +8,0 -> 0,8 +9,4 -> 3,4 +2,2 -> 2,1 +7,0 -> 7,4 +6,4 -> 2,0 +0,9 -> 2,9 +3,4 -> 1,4 +0,0 -> 8,8 +5,5 -> 8,2"; + + #[test] + fn input_parsing() { + let (size, segments) = parse_input(INPUT); + assert_eq!(9,size); + assert_eq!(vec![ + Segment(0,9,5,9), + Segment(8,0,0,8), + Segment(9,4,3,4), + Segment(2,2,2,1), + Segment(7,0,7,4), + Segment(6,4,2,0), + Segment(0,9,2,9), + Segment(3,4,1,4), + Segment(0,0,8,8), + Segment(5,5,8,2), + ],segments); + } + + #[test] + fn examples() { + let (size, segments) = parse_input(INPUT); + assert_eq!(vec![ + 0,0,0,0,0,0,0,1,0,0, + 0,0,1,0,0,0,0,1,0,0, + 0,0,1,0,0,0,0,1,0,0, + 0,0,0,0,0,0,0,1,0,0, + 0,1,1,2,1,1,1,2,1,1, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 2,2,2,1,1,1,0,0,0,0 + ], radar(&segments, size, false)); + assert_eq!(vec![ + 1,0,1,0,0,0,0,1,1,0, + 0,1,1,1,0,0,0,2,0,0, + 0,0,2,0,1,0,1,1,1,0, + 0,0,0,1,0,2,0,2,0,0, + 0,1,1,2,3,1,3,2,1,1, + 0,0,0,1,0,2,0,0,0,0, + 0,0,1,0,0,0,1,0,0,0, + 0,1,0,0,0,0,0,1,0,0, + 1,0,0,0,0,0,0,0,1,0, + 2,2,2,1,1,1,0,0,0,0 + ], radar(&segments, size, true)) + } + +} -- cgit v1.2.3