ben
/
aoc
1
0
Fork 0
aoc/AOC2019/Day10.cs

65 lines
1.9 KiB
C#

namespace AOC2019;
public sealed class Day10() : Day(2019, 10, "Monitoring Station")
{
private HashSet<(int x, int y)>? _asteroids;
private (int x, int y) _best = (x: -1, y: -1);
private int _bestCanSee;
public override void ProcessInput() =>
_asteroids = Input
.Select((r, y) => r.Select((c, x) => (x, y, isAsteroid: c == '#')).ToArray())
.SelectMany(r => r)
.Where(a => a.isAsteroid)
.Select(a => (a.x, a.y))
.ToHashSet();
public override object Part1()
{
foreach (var asteroid in _asteroids!)
{
var canSee = _asteroids
.Except(new[] { asteroid })
.Select(a => (x: a.x - asteroid.x, y: a.y - asteroid.y))
.GroupBy(a => Math.Atan2(a.y, a.x))
.Count();
if (canSee > _bestCanSee)
{
_best = asteroid;
_bestCanSee = canSee;
}
}
return _bestCanSee;
}
public override object Part2()
{
return _asteroids!
.Where(a => a != _best)
.Select(a =>
{
var xDist = a.x - _best.x;
var yDist = a.y - _best.y;
var angle = Math.Atan2(xDist, yDist);
return (a.x, a.y, angle, dist: Math.Sqrt(xDist * xDist + yDist * yDist));
})
.ToLookup(a => a.angle)
.OrderByDescending(a => a.Key)
.Select(a => new Queue<(int x, int y, double angle, double dist)>(a.OrderBy(b => b.dist)))
.Repeat()
.SelectMany(GetValue)
.Skip(199)
.Take(1)
.Select(a => a.x * 100 + a.y)
.Single();
static IEnumerable<(int x, int y, double angle, double dist)> GetValue(
Queue<(int x, int y, double angle, double dist)> q)
{
if (q.Count > 0) yield return q.Dequeue();
}
}
}