2022 day15/rust: make part1 faster
This commit is contained in:
parent
b9b46aab5b
commit
6fb08930bc
1 changed files with 37 additions and 23 deletions
|
@ -2,7 +2,7 @@
|
|||
|
||||
use std::io::stdin;
|
||||
|
||||
use aoc::vec2::{Line, Vec2};
|
||||
use aoc::{vec2::Vec2, SectionRange, UpToTwo};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
struct Sensor {
|
||||
|
@ -56,31 +56,45 @@ fn main() {
|
|||
];
|
||||
assert!(candidates.contains(&sensor.closest_beacon));
|
||||
}
|
||||
let border_points = sensors.iter().filter_map(|sensor| {
|
||||
sensor
|
||||
.position
|
||||
.on_y_with_manhattan_dist(2_000_000, sensor.beacon_distance())
|
||||
});
|
||||
|
||||
let leftmost = border_points
|
||||
.clone()
|
||||
.map(|(left, _right)| left)
|
||||
.min()
|
||||
.unwrap();
|
||||
let rightmost = border_points.map(|(_left, right)| right).max().unwrap();
|
||||
|
||||
let count = Line {
|
||||
start: leftmost,
|
||||
end: rightmost,
|
||||
}
|
||||
.points()
|
||||
.unwrap()
|
||||
.filter(|&p| {
|
||||
sensors
|
||||
let mut ranges: Vec<_> = sensors
|
||||
.iter()
|
||||
.any(|s| p != s.closest_beacon && s.position.manhattan_dist(p) <= s.beacon_distance())
|
||||
.flat_map(|sensor| {
|
||||
let y = 2_000_000;
|
||||
let Some((left, right)) = sensor
|
||||
.position
|
||||
.on_y_with_manhattan_dist(y, sensor.beacon_distance())
|
||||
else {
|
||||
return UpToTwo::Zero;
|
||||
};
|
||||
|
||||
let range = SectionRange::try_new(left.x, right.x).unwrap();
|
||||
if sensor.closest_beacon.y == y {
|
||||
let beacon_pos = sensor.closest_beacon.y;
|
||||
let beacon_pos = SectionRange::try_new(beacon_pos, beacon_pos).unwrap();
|
||||
|
||||
range - beacon_pos
|
||||
} else {
|
||||
UpToTwo::One(range)
|
||||
}
|
||||
})
|
||||
.count();
|
||||
.collect();
|
||||
ranges.sort_unstable();
|
||||
let mut covered = ranges.into_iter();
|
||||
|
||||
let mut count = 0;
|
||||
let mut current_range = covered.next().unwrap();
|
||||
for range in covered {
|
||||
match current_range | range {
|
||||
UpToTwo::Zero => unreachable!(),
|
||||
UpToTwo::One(new) => current_range = new,
|
||||
UpToTwo::Two(_old, new) => {
|
||||
count += current_range.len().get();
|
||||
current_range = new;
|
||||
}
|
||||
}
|
||||
}
|
||||
count += current_range.len().get();
|
||||
|
||||
println!("{:?}", count);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue