aoc2019/Day10.cs

75 lines
2.3 KiB
C#
Raw Normal View History

2019-12-10 06:57:51 +00:00
using System;
using System.Collections.Generic;
using System.Linq;
using aoc2019.lib;
2019-12-10 06:57:51 +00:00
namespace aoc2019
{
2020-12-02 04:50:35 +00:00
internal sealed class Day10 : Day
2019-12-10 06:57:51 +00:00
{
2019-12-12 04:47:22 +00:00
private readonly HashSet<(int x, int y)> asteroids = new HashSet<(int x, int y)>();
private (int x, int y) best = (x: -1, y: -1);
2019-12-10 06:57:51 +00:00
private int bestcansee;
public Day10()
{
2019-12-12 04:47:22 +00:00
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();
}
2019-12-10 06:57:51 +00:00
public override int DayNumber => 10;
2020-12-02 06:58:54 +00:00
protected override string Part1()
2019-12-12 04:47:22 +00:00
{
2019-12-10 06:57:51 +00:00
foreach (var asteroid in asteroids)
{
2019-12-12 04:47:22 +00:00
var cansee = asteroids
.Except(new[] {asteroid})
2019-12-12 04:47:22 +00:00
.Select(a => (x: a.x - asteroid.x, y: a.y - asteroid.y))
.GroupBy(a => Math.Atan2(a.y, a.x))
.Count();
2019-12-10 06:57:51 +00:00
if (cansee > bestcansee)
{
best = asteroid;
bestcansee = cansee;
}
}
2019-12-10 06:57:51 +00:00
return $"{bestcansee}";
}
2020-12-02 06:58:54 +00:00
protected override string Part2()
2019-12-10 06:57:51 +00:00
{
static IEnumerable<(int x, int y, double angle, double dist)> GetValue(
Queue<(int x, int y, double angle, double dist)> q)
2019-12-12 04:47:22 +00:00
{
if (q.Count > 0) yield return q.Dequeue();
}
2019-12-10 06:57:51 +00:00
2019-12-12 04:47:22 +00:00
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()
.ToString();
2019-12-10 06:57:51 +00:00
}
}
}