Program.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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. public class SearchBox
  11. {
  12. // Angle "inférieur gauche"
  13. /*
  14. Y ^
  15. |
  16. |
  17. | Z 7
  18. | /
  19. | /
  20. | /
  21. | /
  22. | /
  23. +______________________> X
  24. */
  25. (int x, int y, int z) Coord { get; }
  26. (int x, int y, int z) OpposedCoord => (Coord.x + Size - 1, Coord.y + Size - 1, Coord.z + Size - 1);
  27. public int Size { get; }
  28. public int Distance => RangedManhattan((0, 0, 0));
  29. public SearchBox(int size, (int, int, int) coord)
  30. {
  31. Size = size;
  32. Coord = coord;
  33. }
  34. int? bots = null;
  35. public int NanoBots
  36. {
  37. get
  38. {
  39. if (bots.HasValue) return bots.Value;
  40. int count = 0;
  41. foreach (var (x, y, z, r) in nanoList)
  42. {
  43. int dist = RangedManhattan((x, y, z));
  44. if (dist <= r) count++;
  45. }
  46. bots = count;
  47. return bots.Value;
  48. }
  49. }
  50. private int RangedManhattan((int x, int y, int z) coord)
  51. {
  52. int manhattan = 0;
  53. // Si la coordonnée du point est située dans la range Coord -> OpposedCoord,
  54. // alors on considère que la distance est de 0 pour la coordonnée en question
  55. if (coord.x < Coord.x) manhattan += Coord.x - coord.x;
  56. if (coord.x > OpposedCoord.x) manhattan += coord.x - OpposedCoord.x;
  57. if (coord.y < Coord.y) manhattan += Coord.y - coord.y;
  58. if (coord.y > OpposedCoord.y) manhattan += coord.y - OpposedCoord.y;
  59. if (coord.z < Coord.z) manhattan += Coord.z - coord.z;
  60. if (coord.z > OpposedCoord.z) manhattan += coord.z - OpposedCoord.z;
  61. return manhattan;
  62. }
  63. public SearchBox[] Split()
  64. {
  65. int size = Size >> 1;
  66. return new SearchBox[8]
  67. {
  68. new SearchBox(size, (Coord.x, Coord. y, Coord.z)),
  69. new SearchBox(size, (Coord.x + size, Coord. y, Coord.z)),
  70. new SearchBox(size, (Coord.x, Coord. y, Coord.z + size)),
  71. new SearchBox(size, (Coord.x + size, Coord. y, Coord.z + size)),
  72. new SearchBox(size, (Coord.x, Coord. y + size, Coord.z)),
  73. new SearchBox(size, (Coord.x + size, Coord. y + size, Coord.z)),
  74. new SearchBox(size, (Coord.x, Coord. y + size, Coord.z + size)),
  75. new SearchBox(size, (Coord.x + size, Coord. y + size, Coord.z + size)),
  76. };
  77. }
  78. }
  79. static List<(int x, int y, int z, int r)> nanoList = new List<(int x, int y, int z, int r)>();
  80. static void Main(string[] args)
  81. {
  82. if (args.Length < 1) return;
  83. if (File.Exists(args[0]) == false) return;
  84. var file = File.OpenText(args[0]);
  85. var reg = new Regex(@"pos=<([\d-,]+)>, r=(\d+)");
  86. do
  87. {
  88. var line = file.ReadLine();
  89. if (line == null) break;
  90. var res = reg.Match(line);
  91. var xyz = res.Groups[1].Value.Split(",").Select(s => int.Parse(s)).ToArray();
  92. var r = int.Parse(res.Groups[2].Value);
  93. nanoList.Add((xyz[0], xyz[1], xyz[2], r));
  94. } while (true);
  95. file.Close();
  96. var sb = Resolve();
  97. Console.WriteLine($"Answer is : {sb.Distance}\nNano bots in range : {sb.NanoBots}");
  98. }
  99. private static SearchBox Resolve()
  100. {
  101. var bsize = (int)Math.Pow(2, 30);
  102. var bcoord = -1 * bsize / 2;
  103. List<SearchBox> SbQueue = new List<SearchBox> { new SearchBox(bsize, (bcoord, bcoord, bcoord)) };
  104. while (true)
  105. {
  106. SbQueue = SbQueue
  107. .OrderByDescending(s => s.NanoBots)
  108. .ThenBy(s => s.Distance)
  109. .ThenBy(s => s.Size)
  110. .ToList();
  111. var first = SbQueue.First();
  112. SbQueue.RemoveAt(0);
  113. if (first.Size == 1)
  114. return first;
  115. SbQueue.AddRange(first.Split());
  116. }
  117. }
  118. }
  119. }