use aoc_runner_derive::{aoc, aoc_generator}; #[derive(Debug)] pub struct Line { x: (i64, i64), y: (i64, i64), } impl Line { fn iter(&self) -> LineIterator { let ret= LineIterator { line: self, px: self.x.0, py: self.y.0, sx: match self.x.0.cmp(&self.x.1) { std::cmp::Ordering::Less => 1, std::cmp::Ordering::Equal => 0, std::cmp::Ordering::Greater => -1, }, sy: match self.y.0.cmp(&self.y.1) { std::cmp::Ordering::Less => 1, std::cmp::Ordering::Equal => 0, std::cmp::Ordering::Greater => -1, }, }; assert!(ret.sx!=0||ret.sy!=0); ret } } #[derive(Debug)] struct LineIterator<'a> { line: &'a Line, px: i64, py: i64, sx: i64, sy: i64, } impl<'a> Iterator for LineIterator<'a> { type Item = (i64, i64); fn next(&mut self) -> Option { let ret = (self.px,self.py); if self.sx>0 && self.px>self.line.x.1 { return None; } if self.sx<0 && self.px0 && self.py>self.line.y.1 { return None; } if self.sy<0 && self.py; #[aoc_generator(day05)] pub fn input_generator(input: &str) -> Data { input .lines() .map(|line| { let parts= line.split(" -> ").collect::>(); let start = parts[0] .split(',') .map(|v| v.parse().unwrap()) .collect::>(); let end = parts[1] .split(',') .map(|v| v.parse().unwrap()) .collect::>(); Line { x: (start[0], end[0]), y: (start[1], end[1]), } }) .collect() } #[aoc(day05, part1)] pub fn solve_part1(input: &Data) -> usize { let mut grid = vec![vec![0u8; 1000]; 1000]; for (x,y) in input.iter().filter(|l| l.x.0==l.x.1||l.y.0==l.y.1).flat_map(|v| v.iter()) { let x: usize=x.try_into().unwrap(); let y: usize=y.try_into().unwrap(); grid[x][y] += 1; } return grid.iter().flatten().filter(|&v| *v > 1).count(); } #[aoc(day05, part2)] pub fn solve_part2(input: &Data) -> usize { let mut grid = vec![vec![0u8; 1000]; 1000]; for (x,y) in input.iter().flat_map(|v| v.iter()) { let x: usize=x.try_into().unwrap(); let y: usize=y.try_into().unwrap(); grid[x][y] += 1; } return grid.iter().flatten().filter(|&v| *v > 1).count(); }