on the way to part2

This commit is contained in:
Stefan Schwarz 2020-05-11 07:37:10 +02:00
parent b7025c1dc2
commit 074d8df6c5

View file

@ -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<Ordering> {
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<XY, Position>,
size_x: usize,
size_y: usize,
}
impl MonitoringStation {
fn laser(&self, root: &XY) -> impl Iterator<Item = XY> + '_ {
let mut map: HashMap<XY, Vec<XY>> = 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::<Vec<XY>>();
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<XY, Position> = 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<dyn std::error::Error>> {
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(())
}