1
0

Program.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Text.RegularExpressions;
  6. namespace D23._2
  7. {
  8. class Program
  9. {
  10. static int Manhattan((int x, int y, int z) a, (int x, int y, int z) b)
  11. {
  12. return Math.Abs(a.x - b.x) + Math.Abs(a.y - b.y) + Math.Abs(a.z - b.z);
  13. }
  14. static int InRange(List<(int x, int y, int z, int r)> nanoList, (int x, int y, int z) coord)
  15. {
  16. int count = 0;
  17. foreach (var n in nanoList)
  18. {
  19. int m = Manhattan(coord, (n.x, n.y, n.z));
  20. if (m <= n.r) count++;
  21. }
  22. return count;
  23. }
  24. static HashSet<(int x, int y, int z)> tested = new HashSet<(int x, int y, int z)>();
  25. 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)
  26. {
  27. var point = coord;
  28. var stack = new List<((int x, int y, int z) pos, int count)>();
  29. int maxCount = 0;
  30. (int x, int y, int z) bestPosition = coord;
  31. int manhattanBest = 0;
  32. stack.Add((point, 0));
  33. while (stack.Count > 0)
  34. {
  35. stack.Sort((a, b) => b.count.CompareTo(a.count));
  36. var first = stack.First();
  37. point = first.pos;
  38. stack.Remove(first);
  39. tested.Add(point);
  40. var count = InRange(nanoList, point);
  41. if (count > maxCount)
  42. {
  43. maxCount = count;
  44. bestPosition = point;
  45. manhattanBest = Manhattan(point, (0, 0, 0));
  46. stack.RemoveAll(s => s.count < maxCount);
  47. Console.Write($"Best is {maxCount} - Manhattan {manhattanBest} \r");
  48. }
  49. else if (count == maxCount)
  50. {
  51. var pmanhattan = Manhattan(point, (0, 0, 0));
  52. if (pmanhattan < manhattanBest)
  53. {
  54. bestPosition = point;
  55. manhattanBest = pmanhattan;
  56. stack.RemoveAll(s => s.count < maxCount);
  57. Console.Write($"Best is {maxCount} - Manhattan {manhattanBest} \r");
  58. }
  59. }
  60. else continue;
  61. foreach (var (mx, my, mz) in MovementList)
  62. {
  63. var mpoint = (point.x + mx * i, point.y + my * i, point.z + mz * i);
  64. if (tested.Contains(mpoint)) continue;
  65. if (stack.Contains((mpoint, count))) continue;
  66. stack.Add((mpoint, count));
  67. }
  68. }
  69. return (manhattanBest, bestPosition);
  70. }
  71. 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) };
  72. static void Main(string[] args)
  73. {
  74. if (args.Length < 1) return;
  75. if (File.Exists(args[0]) == false) return;
  76. var file = File.OpenText(args[0]);
  77. var reg = new Regex(@"pos=<([\d-,]+)>, r=(\d+)");
  78. var nanoList = new List<(int x, int y, int z, int r)>();
  79. do
  80. {
  81. var line = file.ReadLine();
  82. if (line == null) break;
  83. var res = reg.Match(line);
  84. var xyz = res.Groups[1].Value.Split(",").Select(s => int.Parse(s)).ToArray();
  85. var r = int.Parse(res.Groups[2].Value);
  86. nanoList.Add((xyz[0], xyz[1], xyz[2], r));
  87. } while (true);
  88. file.Close();
  89. int inRange = 0;
  90. (int, int, int) best = (0, 0, 0);
  91. foreach (var n in nanoList)
  92. {
  93. int m = InRange(nanoList, (n.x, n.y, n.z));
  94. if (m > inRange)
  95. {
  96. inRange = m;
  97. best = (n.x, n.y, n.z);
  98. }
  99. }
  100. int bestManhattant = 0;
  101. for (var i = (int) Math.Pow(2, 16); i >= 1; i /= 2)
  102. {
  103. Console.Clear();
  104. Console.WriteLine($"Testing with i = {i}");
  105. (var manhattan, var nbest) = Test(nanoList, best, i);
  106. best = nbest;
  107. bestManhattant = manhattan;
  108. }
  109. Console.WriteLine($"\nAnswer is : {bestManhattant}");
  110. }
  111. }
  112. }