[rs] Solve 2022_15 part 2
This commit is contained in:
parent
a8291375ba
commit
f55cfaccce
2 changed files with 60 additions and 22 deletions
|
|
@ -1,2 +1,2 @@
|
||||||
Part 1: 4811413
|
Part 1: 4811413
|
||||||
Part 2: ???
|
Part 2: 13171855019123
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,44 @@ fn parse_coord(coord: &str) -> i32 {
|
||||||
coord.parse().unwrap()
|
coord.parse().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn line_ranges(sensors: &[Sensor], y: i32) -> Vec<(i32, i32)> {
|
||||||
|
let mut raw_ranges = vec![];
|
||||||
|
for sensor in sensors {
|
||||||
|
let dy = (y - sensor.pos.1).abs();
|
||||||
|
if dy > sensor.dist {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let dx = sensor.dist - dy;
|
||||||
|
raw_ranges.push((sensor.pos.0 - dx, sensor.pos.0 + dx));
|
||||||
|
}
|
||||||
|
raw_ranges.sort();
|
||||||
|
|
||||||
|
let mut ranges = vec![];
|
||||||
|
let mut raw_ranges = raw_ranges.into_iter();
|
||||||
|
if let Some(mut cur) = raw_ranges.next() {
|
||||||
|
for range in raw_ranges {
|
||||||
|
if cur.0 <= range.0 && range.0 <= cur.1 {
|
||||||
|
cur.1 = cur.1.max(range.1);
|
||||||
|
} else {
|
||||||
|
ranges.push(cur);
|
||||||
|
cur = range;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ranges.push(cur);
|
||||||
|
}
|
||||||
|
ranges
|
||||||
|
}
|
||||||
|
|
||||||
pub fn solve(input: String) {
|
pub fn solve(input: String) {
|
||||||
let sensors = input
|
let sensors = input
|
||||||
.lines()
|
.lines()
|
||||||
.map(|l| {
|
.map(|l| {
|
||||||
|
// A beacon exactly dist away has 1 field, i. e. x±0
|
||||||
|
// A beacon exactly dist-1 away has 3 fields, i. e. x±1
|
||||||
|
// ...
|
||||||
|
// A beacon exactly 0 away has 2dist+1 fields, i. e. x±dist
|
||||||
|
//
|
||||||
|
// Formula: Go from x-(dist-dy) to x+(dist-dy)
|
||||||
let parts = l.split_whitespace().collect::<Vec<_>>();
|
let parts = l.split_whitespace().collect::<Vec<_>>();
|
||||||
let pos = (parse_coord(parts[2]), parse_coord(parts[3]));
|
let pos = (parse_coord(parts[2]), parse_coord(parts[3]));
|
||||||
let beac = (parse_coord(parts[8]), parse_coord(parts[9]));
|
let beac = (parse_coord(parts[8]), parse_coord(parts[9]));
|
||||||
|
|
@ -23,30 +57,34 @@ pub fn solve(input: String) {
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
// A beacon exactly dist away has 1 field, i. e. x±0
|
|
||||||
// A beacon exactly dist-1 away has 3 fields, i. e. x±1
|
|
||||||
// ...
|
|
||||||
// A beacon exactly 0 away has 2dist+1 fields, i. e. x±dist
|
|
||||||
//
|
|
||||||
// Formula: Go from x-(dist-dy) to x+(dist-dy)
|
|
||||||
let line_at_y = 2000000;
|
let line_at_y = 2000000;
|
||||||
let mut part1 = HashSet::new();
|
let part1_ranges = line_ranges(&sensors, line_at_y);
|
||||||
for (i, sensor) in sensors.iter().enumerate() {
|
let part1_beacons = sensors
|
||||||
eprintln!("Sensor {}", i + 1);
|
.iter()
|
||||||
let dy = (line_at_y - sensor.pos.1).abs();
|
.filter(|s| s.beac.1 == line_at_y)
|
||||||
if dy > sensor.dist {
|
.map(|s| s.beac.0)
|
||||||
continue;
|
.collect::<HashSet<_>>();
|
||||||
|
let mut part1 = 0;
|
||||||
|
for range in part1_ranges {
|
||||||
|
part1 += range.1 - range.0 + 1;
|
||||||
|
for beacon in &part1_beacons {
|
||||||
|
if range.0 <= *beacon && *beacon <= range.1 {
|
||||||
|
part1 -= 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!("Part 1: {part1}");
|
||||||
|
|
||||||
let dx = sensor.dist - dy;
|
for y in 0..=4000000 {
|
||||||
for x in (sensor.pos.0 - dx)..=(sensor.pos.0 + dx) {
|
let mut ranges = line_ranges(&sensors, y);
|
||||||
part1.insert(x);
|
ranges.retain(|(s, e)| *s <= 4000000 && 0 <= *e);
|
||||||
|
if ranges.len() != 1 {
|
||||||
|
// Found our beacon!
|
||||||
|
assert_eq!(ranges.len(), 2);
|
||||||
|
let x = ranges[0].1 + 1;
|
||||||
|
let tuning_frequency = x as i64 * 4000000 + y as i64;
|
||||||
|
println!("Part 2: {tuning_frequency}");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for sensor in &sensors {
|
|
||||||
if sensor.beac.1 == line_at_y {
|
|
||||||
part1.remove(&sensor.beac.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
println!("Part 1: {}", part1.len());
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue