Skip to content

Commit

Permalink
2019: Day 10
Browse files Browse the repository at this point in the history
  • Loading branch information
ericvw committed Apr 24, 2024
1 parent ea3f3a2 commit 5a81c44
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 1 deletion.
42 changes: 42 additions & 0 deletions 2019/input_10.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
..............#.#...............#....#....
#.##.......#....#.#..##........#...#......
..#.....#....#..#.#....#.....#.#.##..#..#.
...........##...#...##....#.#.#....#.##..#
....##....#...........#..#....#......#.###
.#...#......#.#.#.#...#....#.##.##......##
#.##....#.....#.....#...####........###...
.####....#.......#...##..#..#......#...#..
...............#...........#..#.#.#.......
........#.........##...#..........#..##...
...#..................#....#....##..#.....
.............#..#.#.........#........#.##.
...#.#....................##..##..........
.....#.#...##..............#...........#..
......#..###.#........#.....#.##.#......#.
#......#.#.....#...........##.#.....#..#.#
.#.............#..#.....##.....###..#..#..
.#...#.....#.....##.#......##....##....#..
.........#.#..##............#..#...#......
..#..##...#.#..#....#..#.#.......#.##.....
#.......#.#....#.#..##.#...#.......#..###.
.#..........#...##.#....#...#.#.........#.
..#.#.......##..#.##..#.......#.###.......
...#....###...#......#..#.....####........
.............#.#..........#....#......#...
#................#..................#.###.
..###.........##...##..##.................
.#.........#.#####..#...##....#...##......
........#.#...#......#.................##.
.##.....#..##.##.#....#....#......#.#....#
.....#...........#.............#.....#....
........#.##.#...#.###.###....#.#......#..
..#...#.......###..#...#.##.....###.....#.
....#.....#..#.....#...#......###...###...
#..##.###...##.....#.....#....#...###..#..
........######.#...............#...#.#...#
...#.....####.##.....##...##..............
###..#......#...............#......#...#..
#..#...#.#........#.#.#...#..#....#.#.####
#..#...#..........##.#.....##........#.#..
........#....#..###..##....#.#.......##..#
.................##............#.......#..
117 changes: 117 additions & 0 deletions 2019/src/bin/puzzle_10.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
use std::collections::BinaryHeap;
use std::collections::HashMap;
use std::io;

use aoc2019::grid::Point;

#[derive(Ord, PartialOrd, Eq, PartialEq)]
struct AsteroidMetadata {
loc: Point,
distance: u32,
}

fn gcd(mut a: i32, mut b: i32) -> i32 {
while b != 0 {
let t = b;
b = a % b;
a = t;
}

a.abs()
}

fn distances_from(
monitoring_station: Point,
asteroids: &[Point],
) -> HashMap<Point, Vec<AsteroidMetadata>> {
let mut result: HashMap<Point, Vec<AsteroidMetadata>> = HashMap::new();

for &a in asteroids {
if a == monitoring_station {
continue;
}

let delta = a - monitoring_station;
let largest_factor = gcd(delta.x, delta.y);

result
.entry(Point {
x: delta.x / largest_factor,
y: delta.y / largest_factor,
})
.or_default()
.push(AsteroidMetadata {
loc: a,
distance: monitoring_station.manhattan_distance(a),
});
}

result
}

fn vaporize_until(asteroids: &HashMap<Point, Vec<AsteroidMetadata>>, count: u32) -> Point {
let mut visible: HashMap<_, _> = asteroids
.iter()
.map(|(k, v)| (k, v.iter().collect::<BinaryHeap<&AsteroidMetadata>>()))
.collect();

let mut vaporization_order: Vec<_> = asteroids.keys().collect();

// XXX: Note these are vectors (i.e., (dx, dy)) of the asteroids relative to the monitoring
// station. We reverse the arguments to atan2() from atan2(dy, dx) to atan2(dx, dy) to
// achieve a 90°CCW rotation and a vertical flip of the coordiante system. Sorting by the
// reversed arguments achieves a CCW sweep. To get a CW sweep, we reverse the order.
vaporization_order.sort_by(|a, b| {
f64::from(a.x)
.atan2(f64::from(a.y))
.total_cmp(&f64::from(b.x).atan2(f64::from(b.y)))
});
vaporization_order.reverse();

let mut result: Point = Default::default();
let mut i = 0;
let count = usize::try_from(count).unwrap();
while i < count {
result = match visible
.get_mut(vaporization_order[i % vaporization_order.len()])
.unwrap()
.pop()
{
Some(a) => a.loc,
None => continue,
};
i += 1;
}

result
}

fn main() {
// XXX: Note that y-coordinate is from the top, and x-coordinate is from the left.
let mut asteroids = vec![];
for (y, row) in io::stdin().lines().map(|line| line.unwrap()).enumerate() {
for (x, c) in row.chars().enumerate() {
if c == '#' {
asteroids.push(Point {
x: i32::try_from(x).unwrap(),
y: i32::try_from(y).unwrap(),
});
}
}
}

let dists_from_station = asteroids
.iter()
.map(|&loc| (loc, distances_from(loc, &asteroids)))
.max_by(|a, b| a.1.len().cmp(&b.1.len()))
.unwrap()
.1;

println!("Part 1: {}", dists_from_station.len());

const BETTED_ASTEROID_VAPORIZED: u32 = 200;

let asteroid = vaporize_until(&dists_from_station, BETTED_ASTEROID_VAPORIZED);

println!("Part 2: {}", asteroid.x * 100 + asteroid.y);
}
14 changes: 13 additions & 1 deletion 2019/src/grid.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::ops::Add;
use std::ops::Sub;

#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)]
#[derive(Debug, Default, Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
pub struct Point {
pub x: i32,
pub y: i32,
Expand All @@ -22,3 +23,14 @@ impl Add for Point {
}
}
}

impl Sub for Point {
type Output = Self;

fn sub(self, other: Self) -> Self {
Self {
x: self.x - other.x,
y: self.y - other.y,
}
}
}

0 comments on commit 5a81c44

Please sign in to comment.