diff --git a/src/day10/main.rs b/src/day10/main.rs index 23f70db..1ca696e 100644 --- a/src/day10/main.rs +++ b/src/day10/main.rs @@ -1,3 +1,4 @@ +use std::cmp::Ordering; use std::collections::{HashMap, HashSet}; use std::fs::File; use std::io::{BufRead, BufReader}; @@ -45,6 +46,18 @@ impl Sub for &XY { } } +impl PartialOrd for XY { + fn partial_cmp(&self, other: &XY) -> Option { + self.angle().partial_cmp(&other.angle()) + } +} + +impl Ord for XY { + fn cmp(&self, other: &XY) -> Ordering { + self.angle().partial_cmp(&other.angle()).unwrap() + } +} + impl XY { fn direction(&self) -> Self { let d = gcd(self.y, self.x).abs(); @@ -57,13 +70,57 @@ impl XY { self.clone() } } + + fn angle(&self) -> f64 { + (self.y as f64).atan2(self.x as f64) * (180 as f64 / std::f64::consts::PI) + } } struct MonitoringStation { map: HashMap, + size_x: usize, + size_y: usize, } impl MonitoringStation { + fn laser(&self, root: &XY) -> impl Iterator + '_ { + let mut map: HashMap> = HashMap::new(); + map = self + .map + .iter() + .filter_map(|(xy, pos)| { + if *pos == Position::Empty { + return None; + } + let rel = xy - &root; + Some((xy, rel.direction())) + }) + .fold(map, |mut acc, (xy, dir)| { + acc.entry(dir).or_insert(vec![]).push(xy.clone()); + acc + }); + let mut angles = map.keys().cloned().collect::>(); + angles.sort(); + + let mut popped = true; + let mut cycles = 0; + while popped { + popped = false; + cycles += 1; + angles.iter().for_each(|xy| match map.get_mut(xy) { + Some(xy) => { + if let Some(xy) = xy.pop() { + popped = true; + println!("{:?}", xy) + } + } + None => (), + }); + } + println!("cycles: {}", cycles); + self.map.iter().map(|(xy, _)| xy.clone()) + } + fn find(&self) -> (usize, XY) { let best = (0, XY::from((0, 0))); self.map @@ -105,10 +162,12 @@ where { fn from(reader: T) -> Self { let map: HashMap = HashMap::new(); + let mut size_y = 0; let map = reader .split(b'\n') .enumerate() .flat_map(|(y, line)| { + size_y += 1; line.unwrap() .iter() .enumerate() @@ -123,15 +182,23 @@ where map.insert(xy.clone(), p.clone()); map }); - MonitoringStation { map } + let size_x = map.iter().count() / size_y; + MonitoringStation { + map, + size_x, + size_y, + } } } fn main() -> Result<(), Box> { let f = File::open("input10")?; let reader = BufReader::new(f); - let best = MonitoringStation::from(reader).find(); + let station = MonitoringStation::from(reader); + let best = station.find(); + let test = station.laser(&best.1).next(); println!("best: {:?}", best); + println!("test: {:?}", test); Ok(()) }