on the way to part2
This commit is contained in:
parent
b7025c1dc2
commit
074d8df6c5
1 changed files with 69 additions and 2 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
use std::cmp::Ordering;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufRead, BufReader};
|
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 {
|
impl XY {
|
||||||
fn direction(&self) -> Self {
|
fn direction(&self) -> Self {
|
||||||
let d = gcd(self.y, self.x).abs();
|
let d = gcd(self.y, self.x).abs();
|
||||||
|
@ -57,13 +70,57 @@ impl XY {
|
||||||
self.clone()
|
self.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn angle(&self) -> f64 {
|
||||||
|
(self.y as f64).atan2(self.x as f64) * (180 as f64 / std::f64::consts::PI)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MonitoringStation {
|
struct MonitoringStation {
|
||||||
map: HashMap<XY, Position>,
|
map: HashMap<XY, Position>,
|
||||||
|
size_x: usize,
|
||||||
|
size_y: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MonitoringStation {
|
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) {
|
fn find(&self) -> (usize, XY) {
|
||||||
let best = (0, XY::from((0, 0)));
|
let best = (0, XY::from((0, 0)));
|
||||||
self.map
|
self.map
|
||||||
|
@ -105,10 +162,12 @@ where
|
||||||
{
|
{
|
||||||
fn from(reader: T) -> Self {
|
fn from(reader: T) -> Self {
|
||||||
let map: HashMap<XY, Position> = HashMap::new();
|
let map: HashMap<XY, Position> = HashMap::new();
|
||||||
|
let mut size_y = 0;
|
||||||
let map = reader
|
let map = reader
|
||||||
.split(b'\n')
|
.split(b'\n')
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.flat_map(|(y, line)| {
|
.flat_map(|(y, line)| {
|
||||||
|
size_y += 1;
|
||||||
line.unwrap()
|
line.unwrap()
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
|
@ -123,15 +182,23 @@ where
|
||||||
map.insert(xy.clone(), p.clone());
|
map.insert(xy.clone(), p.clone());
|
||||||
map
|
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>> {
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let f = File::open("input10")?;
|
let f = File::open("input10")?;
|
||||||
let reader = BufReader::new(f);
|
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!("best: {:?}", best);
|
||||||
|
println!("test: {:?}", test);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue