76 lines
2.6 KiB
Rust
76 lines
2.6 KiB
Rust
use std::collections::HashSet;
|
|
|
|
#[allow(dead_code)]
|
|
pub fn run() {
|
|
let asteroids: HashSet<(i32, i32)> = std::fs::read_to_string("input/day10.txt")
|
|
.unwrap()
|
|
.lines()
|
|
.enumerate()
|
|
.map(|(y, line)| {
|
|
line.chars()
|
|
.enumerate()
|
|
.filter(|(_, it)| *it == '#')
|
|
.map(move |(x, _)| (x as i32, y as i32))
|
|
})
|
|
.flatten()
|
|
.collect();
|
|
task1(&asteroids);
|
|
}
|
|
|
|
fn task1(asteroids: &HashSet<(i32, i32)>) {
|
|
let max = asteroids
|
|
.iter()
|
|
.map(|asteroid| {
|
|
println!("inspecting {:?}", asteroid);
|
|
// map to number of other asteroids it sees
|
|
let mut others = asteroids.clone();
|
|
others.remove(&asteroid);
|
|
// count those asteroids that are not blocked by another
|
|
let count = others
|
|
.iter()
|
|
.filter(|target| {
|
|
let blocker = others
|
|
.iter()
|
|
.find(|occluder| blocks_view(*asteroid, **target, **occluder));
|
|
if let Some(occluder) = blocker {
|
|
println!("{:?} -> X{:?}X -> {:?}", asteroid, occluder, target);
|
|
}
|
|
!blocker.is_some()
|
|
})
|
|
.inspect(|target| println!("sees {:?}", target))
|
|
.count();
|
|
println!("{:?}: {}", asteroid, count);
|
|
count
|
|
})
|
|
.max()
|
|
.unwrap();
|
|
println!(
|
|
"Task 1: maximum visible asteroids from another asteroid are {}",
|
|
max
|
|
);
|
|
}
|
|
|
|
fn blocks_view(pov: (i32, i32), target: (i32, i32), occluder: (i32, i32)) -> bool {
|
|
if occluder == target {
|
|
return false;
|
|
}
|
|
fn d(a: (i32, i32), b: (i32, i32)) -> f32 {
|
|
((a.0 - b.0) as f32).powi(2) + ((a.1 - b.1) as f32).powi(2).sqrt()
|
|
}
|
|
// using polar coordinates
|
|
let alpha_occluder = ((occluder.1 - pov.1) as f32).atan2((occluder.0 - pov.0) as f32);
|
|
let alpha_target = ((target.1 - pov.1) as f32).atan2((target.0 - pov.0) as f32);
|
|
(alpha_occluder - alpha_target).abs() <= std::f32::EPSILON && d(pov, target) > d(pov, occluder)
|
|
}
|
|
|
|
mod test {
|
|
#[test]
|
|
fn block_test() {
|
|
assert_eq!(true, super::blocks_view((3, 4), (1, 0), (2, 2)));
|
|
assert_eq!(false, super::blocks_view((3, 4), (2, 2), (1, 0)));
|
|
assert_eq!(false, super::blocks_view((3, 4), (1, 0), (1, 2)));
|
|
assert_eq!(true, super::blocks_view((4, 4), (4, 0), (4, 3)));
|
|
assert_eq!(false, super::blocks_view((3, 2), (1, 0), (4, 3)));
|
|
}
|
|
}
|