remove non-astroids from map
This commit is contained in:
parent
f12c16a06a
commit
9b09b974eb
1 changed files with 30 additions and 45 deletions
|
@ -1,4 +1,3 @@
|
||||||
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};
|
||||||
|
@ -46,18 +45,6 @@ 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();
|
||||||
|
@ -88,20 +75,17 @@ impl XY {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MonitoringStation {
|
struct MonitoringStation {
|
||||||
map: HashMap<XY, Position>,
|
map: Vec<XY>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MonitoringStation {
|
impl MonitoringStation {
|
||||||
fn laser(&self, root: &XY, skip: usize, n: usize) -> Vec<XY> {
|
fn laser(&self, root: &XY, skip: usize, n: usize) -> Vec<XY> {
|
||||||
let mut map: HashMap<XY, Vec<XY>> = HashMap::new();
|
let mut map: HashMap<XY, Vec<&XY>> = HashMap::new();
|
||||||
// collect vec for each direction
|
// collect vec for each direction
|
||||||
map = self
|
map = self
|
||||||
.map
|
.map
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(xy, pos)| {
|
.filter_map(|xy| {
|
||||||
if *pos == Position::Empty {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
if xy == root {
|
if xy == root {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -109,7 +93,7 @@ impl MonitoringStation {
|
||||||
Some((xy, rel.direction()))
|
Some((xy, rel.direction()))
|
||||||
})
|
})
|
||||||
.fold(map, |mut acc, (xy, dir)| {
|
.fold(map, |mut acc, (xy, dir)| {
|
||||||
acc.entry(dir).or_insert(vec![]).push(xy.clone());
|
acc.entry(dir).or_insert(vec![]).push(xy);
|
||||||
acc
|
acc
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -122,8 +106,9 @@ impl MonitoringStation {
|
||||||
|
|
||||||
// lets iterate over sorted angles
|
// lets iterate over sorted angles
|
||||||
let mut angles = map.keys().cloned().collect::<Vec<XY>>();
|
let mut angles = map.keys().cloned().collect::<Vec<XY>>();
|
||||||
angles.sort();
|
angles.sort_by(|a, b| a.angle().partial_cmp(&b.angle()).unwrap());
|
||||||
|
|
||||||
|
// cycle around and return first element of each vec
|
||||||
angles
|
angles
|
||||||
.iter()
|
.iter()
|
||||||
.cycle()
|
.cycle()
|
||||||
|
@ -140,23 +125,21 @@ impl MonitoringStation {
|
||||||
.flatten()
|
.flatten()
|
||||||
.skip(skip)
|
.skip(skip)
|
||||||
.take(n)
|
.take(n)
|
||||||
|
.cloned()
|
||||||
.collect::<Vec<XY>>()
|
.collect::<Vec<XY>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
let best = self
|
||||||
|
.map
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(_, pos)| **pos == Position::Astroid)
|
.map(|root| {
|
||||||
.map(|(root, _)| {
|
|
||||||
let insight = self
|
let insight = self
|
||||||
.map
|
.map
|
||||||
.iter()
|
.iter()
|
||||||
// get direction to any of the astroids
|
// get direction to any of the astroids
|
||||||
.filter_map(|(xy, pos)| {
|
.filter_map(|xy| {
|
||||||
if *pos == Position::Empty {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let rel = xy - root;
|
let rel = xy - root;
|
||||||
Some(rel.direction())
|
Some(rel.direction())
|
||||||
})
|
})
|
||||||
|
@ -169,12 +152,17 @@ impl MonitoringStation {
|
||||||
- 1;
|
- 1;
|
||||||
(insight, root)
|
(insight, root)
|
||||||
})
|
})
|
||||||
.fold(best, |acc, astroid| {
|
.fold(
|
||||||
if astroid.0 > acc.0 {
|
best,
|
||||||
return (astroid.0, astroid.1.clone());
|
|acc, astroid| {
|
||||||
}
|
if astroid.0 > acc.0 {
|
||||||
acc
|
astroid
|
||||||
})
|
} else {
|
||||||
|
acc
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
(best.0, best.1.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,25 +171,22 @@ where
|
||||||
T: BufRead,
|
T: BufRead,
|
||||||
{
|
{
|
||||||
fn from(reader: T) -> Self {
|
fn from(reader: T) -> Self {
|
||||||
let map: HashMap<XY, Position> = HashMap::new();
|
|
||||||
let map = reader
|
let map = reader
|
||||||
.split(b'\n')
|
.split(b'\n')
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.flat_map(|(y, line)| {
|
.flat_map(|(y, line)| {
|
||||||
line.unwrap()
|
line.unwrap()
|
||||||
.iter()
|
.into_iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(x, c)| {
|
.filter_map(move |(x, c)| {
|
||||||
let xy = XY::from((x, y));
|
let xy = XY::from((x, y));
|
||||||
let p = Position::from(c);
|
match Position::from(&c) {
|
||||||
(xy, p)
|
Position::Astroid => Some(xy),
|
||||||
|
Position::Empty => None,
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.collect::<Vec<(XY, Position)>>()
|
|
||||||
})
|
})
|
||||||
.fold(map, |mut map, (xy, p)| {
|
.collect::<Vec<XY>>();
|
||||||
map.insert(xy.clone(), p.clone());
|
|
||||||
map
|
|
||||||
});
|
|
||||||
MonitoringStation { map }
|
MonitoringStation { map }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue