| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Text.RegularExpressions;
- namespace D23._2
- {
- class Program
- {
- static int Manhattan((int x, int y, int z) a, (int x, int y, int z) b)
- {
- return Math.Abs(a.x - b.x) + Math.Abs(a.y - b.y) + Math.Abs(a.z - b.z);
- }
- static int InRange(List<(int x, int y, int z, int r)> nanoList, (int x, int y, int z) coord)
- {
- int count = 0;
- foreach (var n in nanoList)
- {
- int m = Manhattan(coord, (n.x, n.y, n.z));
- if (m <= n.r) count++;
- }
- return count;
- }
- static HashSet<(int x, int y, int z)> tested = new HashSet<(int x, int y, int z)>();
- static (int, (int, int, int)) Test(List<(int x, int y, int z, int r)> nanoList, (int x, int y, int z) coord, int i)
- {
- var point = coord;
- var stack = new List<((int x, int y, int z) pos, int count)>();
- int maxCount = 0;
- (int x, int y, int z) bestPosition = coord;
- int manhattanBest = 0;
- stack.Add((point, 0));
- while (stack.Count > 0)
- {
- stack.Sort((a, b) => b.count.CompareTo(a.count));
- var first = stack.First();
- point = first.pos;
- stack.Remove(first);
- tested.Add(point);
- var count = InRange(nanoList, point);
- if (count > maxCount)
- {
- maxCount = count;
- bestPosition = point;
- manhattanBest = Manhattan(point, (0, 0, 0));
- stack.RemoveAll(s => s.count < maxCount);
- Console.Write($"Best is {maxCount} - Manhattan {manhattanBest} \r");
- }
- else if (count == maxCount)
- {
- var pmanhattan = Manhattan(point, (0, 0, 0));
- if (pmanhattan < manhattanBest)
- {
- bestPosition = point;
- manhattanBest = pmanhattan;
- stack.RemoveAll(s => s.count < maxCount);
- Console.Write($"Best is {maxCount} - Manhattan {manhattanBest} \r");
- }
- }
- else continue;
- foreach (var (mx, my, mz) in MovementList)
- {
- var mpoint = (point.x + mx * i, point.y + my * i, point.z + mz * i);
- if (tested.Contains(mpoint)) continue;
- if (stack.Contains((mpoint, count))) continue;
- stack.Add((mpoint, count));
- }
- }
- return (manhattanBest, bestPosition);
- }
- static (int mx, int my, int mz)[] MovementList = new[] { (0, -1, 0), (0, 1, 0), (-1, 0, 0), (1, 0, 0), (0, 0, -1), (0, 0, 1) };
- static void Main(string[] args)
- {
- if (args.Length < 1) return;
- if (File.Exists(args[0]) == false) return;
- var file = File.OpenText(args[0]);
- var reg = new Regex(@"pos=<([\d-,]+)>, r=(\d+)");
- var nanoList = new List<(int x, int y, int z, int r)>();
- do
- {
- var line = file.ReadLine();
- if (line == null) break;
- var res = reg.Match(line);
- var xyz = res.Groups[1].Value.Split(",").Select(s => int.Parse(s)).ToArray();
- var r = int.Parse(res.Groups[2].Value);
- nanoList.Add((xyz[0], xyz[1], xyz[2], r));
- } while (true);
- file.Close();
- int inRange = 0;
- (int, int, int) best = (0, 0, 0);
- foreach (var n in nanoList)
- {
- int m = InRange(nanoList, (n.x, n.y, n.z));
- if (m > inRange)
- {
- inRange = m;
- best = (n.x, n.y, n.z);
- }
- }
- int bestManhattant = 0;
- for (var i = (int) Math.Pow(2, 16); i >= 1; i /= 2)
- {
- Console.Clear();
- Console.WriteLine($"Testing with i = {i}");
- (var manhattan, var nbest) = Test(nanoList, best, i);
- best = nbest;
- bestManhattant = manhattan;
- }
- Console.WriteLine($"\nAnswer is : {bestManhattant}");
- }
- }
- }
|