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 std::io::stdin;
|
||||||
|
|
||||||
use aoc::vec2::{Line, Vec2};
|
use aoc::{vec2::Vec2, SectionRange, UpToTwo};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
struct Sensor {
|
struct Sensor {
|
||||||
|
@ -56,31 +56,45 @@ fn main() {
|
||||||
];
|
];
|
||||||
assert!(candidates.contains(&sensor.closest_beacon));
|
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
|
let mut ranges: Vec<_> = sensors
|
||||||
.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
|
|
||||||
.iter()
|
.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);
|
println!("{:?}", count);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue