public static void P2() { var s = Utilities.GetLinesFromFile("Day10.txt").Select(x => x.Replace(",", "").ToArray()).ToArray(); var arr = new char[s.GetLength(0), s.GetLength(0)]; for (int i = 0; i < s.GetLength(0); i++) { for (int j = 0; j < s[0].GetLength(0); j++) { arr[i, j] = s[i][j]; } } int[] centerpoint = new int[] { 20, 23 }; arr[centerpoint[0], centerpoint[1]] = '*'; var angles = new Dictionary <float, List <Asteroid> >(); for (int i = 0; i < s.GetLength(0); i++) { for (int j = 0; j < s[0].GetLength(0); j++) { if (arr[i, j] == '#') { var angle = (float)(Math.Atan2((centerpoint[0] - i), (centerpoint[1] - j)) * (180 / (Math.PI))); var x1 = (angle < 0 ? 360 : 0); angle = angle + (angle < 0 ? 360 : 0); angle = angle + (angle < 90 ? 360 : 0); //Console.WriteLine($"x{j} y{i} angle: {angle}"); if (!angles.ContainsKey(angle)) { angles[angle] = new List <Asteroid>(); } angles[angle].Add(new Asteroid() { coords = $"x{j} y{i}", dist = Distance(centerpoint, new int[] { j, i }), x = j, y = i }); } } } var targets = angles.OrderBy(a => a.Key).ToList(); Asteroid lasthit = new Asteroid(); int countdown = 200; int it = 0; while (countdown > 0) { if (targets[it].Value.Count > 0) { var tdist = targets[it].Value.Min(x => x.dist); var t = targets[it].Value.First(v => v.dist == tdist); lasthit = t; Console.WriteLine($"PEW! {t.coords}"); targets[it].Value.Remove(t); countdown--; } it++; if (it >= targets.Count()) { it = 0; } } Console.WriteLine($"Last ateroid hit: {lasthit.coords} answer is: {lasthit.answer}"); }
public static int Vaporize200Asteroids(string[] asteroidMap) { if (asteroidMap is null || asteroidMap.Length == 0) { throw new ArgumentException("map null or empty", nameof(asteroidMap)); } var asteroids = new Dictionary <Point, Asteroid>(); var mapXMax = asteroidMap[0].Length - 1; var mapYMax = asteroidMap.Length - 1; for (int y1 = 0; y1 <= mapYMax; y1++) { for (int x1 = 0; x1 <= mapXMax; x1++) { if (asteroidMap[y1].Substring(x1, 1) == "#") { var asteroid = new Asteroid(x1, y1); asteroids.Add(asteroid.Location, asteroid); for (int y2 = 0; y2 <= mapYMax; y2++) { for (int x2 = 0; x2 <= mapXMax; x2++) { if (asteroidMap[y2].Substring(x2, 1) == "#" && !(x2 == x1 && y2 == y1)) { var angle = (int)(((Math.Atan2((double)y2 - y1, (double)x2 - x1) * (180 / Math.PI) + 360) % 360) * 100); // multiplied by 100 so the precision is greater and I can still use array with int index asteroid.AsteroidInView[angle] = true; if (!(asteroid.AsteroidsInView.TryGetValue(angle, out var asteroidsInLine))) { asteroidsInLine = new List <Asteroid>(); asteroid.AsteroidsInView.Add(angle, asteroidsInLine); } asteroidsInLine.Add(new Asteroid(x2, y2, x1, y1)); } } } } } } var maxAsteroidsInView = int.MinValue; Asteroid bestAsteroid = null; foreach (var asteroid in asteroids) { var asteroidsSeen = asteroid.Value.AsteroidInView.Count(value => value); if (asteroidsSeen > maxAsteroidsInView) { maxAsteroidsInView = asteroidsSeen; bestAsteroid = asteroid.Value; } } Asteroid target = null; if (bestAsteroid != null) { var asteroidsVaporized = 0; var angle = 36000 - (90 * 100); // zero is at X acsel. Se rewind 90 degrees (times 100 because the index) while (asteroidsVaporized < 200) { if (bestAsteroid.AsteroidsInView.TryGetValue(angle, out var asteroidsInSight)) { var minDistance = asteroidsInSight.Min(a => a.Vaporized ? double.MaxValue : a.Distance); target = asteroidsInSight.Find(a => a.Distance == minDistance); target.Vaporize(); asteroidsVaporized += 1; } angle += 1; if (angle % 36000 == 0) { angle = 0; } } } return(target == null ? throw new Exception("something went wrong") : target.X * 100 + target.Y); }
private static double Angle(Asteroid baseAsteroid, Asteroid asteroid) { return(Math.Atan2(asteroid.Y - baseAsteroid.Y, asteroid.X - baseAsteroid.X)); }
public AsteroidMap VisibilityMap(int stationRow, int stationCol) { // Create a map of what other asteroids are visible if i put a station on the inputted asteroid. Asteroid station = new Asteroid(stationRow, stationCol, null); AsteroidMap map = new AsteroidMap((string[])this.rows.Clone(), station); station.map = map; // If there is no asteroid in the inputted area, return null; if (map.GetCell(stationRow, stationCol) != ASTEROID) { Console.WriteLine("ERROR! You asked for a visibility map for a location that has no asteroid."); return(null); } // Logic: // Look directly to the left of me, find the first asteroid, and consider everything else blocked. // Look directly to the right of me, find the first asteroid, and consider everything else blocked. // Look at the entire row above me. Find asteroids, and block everything behind it. // And then move up a row. // Look at the entire row below me. Find any asteroids, and block everything behind it. for (int columnId = (stationCol - 1); columnId >= 0; columnId--) { int rowId = stationRow; if (map.GetCell(rowId, columnId) == ASTEROID) { map.SetCellVisible(rowId, columnId, stationRow, stationCol); // break; } } for (int columnId = (stationCol + 1); columnId < this.mapWidth; columnId++) { int rowId = stationRow; if (map.GetCell(rowId, columnId) == ASTEROID) { map.SetCellVisible(rowId, columnId, stationRow, stationCol); //break; } } for (int rowId = (stationRow - 1); rowId >= 0; rowId--) { for (int colId = 0; colId < this.mapWidth; colId++) { if (map.GetCell(rowId, colId) == ASTEROID) { map.SetCellVisible(rowId, colId, stationRow, stationCol); //break; } } } for (int rowId = (stationRow + 1); rowId < this.mapHeight; rowId++) { for (int colId = 0; colId < this.mapWidth; colId++) { if (map.GetCell(rowId, colId) == ASTEROID) { map.SetCellVisible(rowId, colId, stationRow, stationCol); //break; } } } return(map); }
public int GetDistanceTo(Asteroid asteroid) { return(Math.Abs(asteroid.X - this.X) + Math.Abs(asteroid.Y - this.Y)); }