|
|
@@ -8,79 +8,94 @@ namespace D23._2
|
|
|
{
|
|
|
class Program
|
|
|
{
|
|
|
- static int Manhattan((int x, int y, int z) a, (int x, int y, int z) b)
|
|
|
+ public class SearchBox
|
|
|
{
|
|
|
- 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)
|
|
|
+ // Angle "inférieur gauche"
|
|
|
+ /*
|
|
|
+
|
|
|
+ Y ^
|
|
|
+ |
|
|
|
+ |
|
|
|
+ | Z 7
|
|
|
+ | /
|
|
|
+ | /
|
|
|
+ | /
|
|
|
+ | /
|
|
|
+ | /
|
|
|
+ +______________________> X
|
|
|
+
|
|
|
+
|
|
|
+ */
|
|
|
+ (int x, int y, int z) Coord { get; }
|
|
|
+
|
|
|
+ (int x, int y, int z) OpposedCoord => (Coord.x + Size - 1, Coord.y + Size - 1, Coord.z + Size - 1);
|
|
|
+
|
|
|
+ public int Size { get; }
|
|
|
+
|
|
|
+ public int Distance => RangedManhattan((0, 0, 0));
|
|
|
+
|
|
|
+ public SearchBox(int size, (int, int, int) coord)
|
|
|
{
|
|
|
- int m = Manhattan(coord, (n.x, n.y, n.z));
|
|
|
- if (m <= n.r) count++;
|
|
|
+ Size = size;
|
|
|
+ Coord = coord;
|
|
|
}
|
|
|
- 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? bots = null;
|
|
|
+ public int NanoBots
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ if (bots.HasValue) return bots.Value;
|
|
|
|
|
|
- int maxCount = 0;
|
|
|
- (int x, int y, int z) bestPosition = coord;
|
|
|
- int manhattanBest = 0;
|
|
|
+ int count = 0;
|
|
|
+ foreach (var (x, y, z, r) in nanoList)
|
|
|
+ {
|
|
|
+ int dist = RangedManhattan((x, y, z));
|
|
|
+ if (dist <= r) count++;
|
|
|
+ }
|
|
|
+ bots = count;
|
|
|
|
|
|
- stack.Add((point, 0));
|
|
|
+ return bots.Value;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- while (stack.Count > 0)
|
|
|
+ private int RangedManhattan((int x, int y, int z) coord)
|
|
|
{
|
|
|
- stack.Sort((a, b) => b.count.CompareTo(a.count));
|
|
|
+ int manhattan = 0;
|
|
|
|
|
|
- var first = stack.First();
|
|
|
- point = first.pos;
|
|
|
- stack.Remove(first);
|
|
|
+ // Si la coordonnée du point est située dans la range Coord -> OpposedCoord,
|
|
|
+ // alors on considère que la distance est de 0 pour la coordonnée en question
|
|
|
+ if (coord.x < Coord.x) manhattan += Coord.x - coord.x;
|
|
|
+ if (coord.x > OpposedCoord.x) manhattan += coord.x - OpposedCoord.x;
|
|
|
|
|
|
- tested.Add(point);
|
|
|
+ if (coord.y < Coord.y) manhattan += Coord.y - coord.y;
|
|
|
+ if (coord.y > OpposedCoord.y) manhattan += coord.y - OpposedCoord.y;
|
|
|
|
|
|
- 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;
|
|
|
+ if (coord.z < Coord.z) manhattan += Coord.z - coord.z;
|
|
|
+ if (coord.z > OpposedCoord.z) manhattan += coord.z - OpposedCoord.z;
|
|
|
|
|
|
- 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 manhattan;
|
|
|
}
|
|
|
|
|
|
- return (manhattanBest, bestPosition);
|
|
|
+ public SearchBox[] Split()
|
|
|
+ {
|
|
|
+ int size = Size >> 1;
|
|
|
+ return new SearchBox[8]
|
|
|
+ {
|
|
|
+ new SearchBox(size, (Coord.x, Coord. y, Coord.z)),
|
|
|
+ new SearchBox(size, (Coord.x + size, Coord. y, Coord.z)),
|
|
|
+ new SearchBox(size, (Coord.x, Coord. y, Coord.z + size)),
|
|
|
+ new SearchBox(size, (Coord.x + size, Coord. y, Coord.z + size)),
|
|
|
+
|
|
|
+ new SearchBox(size, (Coord.x, Coord. y + size, Coord.z)),
|
|
|
+ new SearchBox(size, (Coord.x + size, Coord. y + size, Coord.z)),
|
|
|
+ new SearchBox(size, (Coord.x, Coord. y + size, Coord.z + size)),
|
|
|
+ new SearchBox(size, (Coord.x + size, Coord. y + size, Coord.z + size)),
|
|
|
+ };
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- 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 List<(int x, int y, int z, int r)> nanoList = new List<(int x, int y, int z, int r)>();
|
|
|
static void Main(string[] args)
|
|
|
{
|
|
|
if (args.Length < 1) return;
|
|
|
@@ -90,8 +105,6 @@ namespace D23._2
|
|
|
|
|
|
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();
|
|
|
@@ -107,30 +120,35 @@ namespace D23._2
|
|
|
|
|
|
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);
|
|
|
- }
|
|
|
- }
|
|
|
+ var sb = Resolve();
|
|
|
|
|
|
- int bestManhattant = 0;
|
|
|
- for (var i = (int) Math.Pow(2, 16); i >= 1; i /= 2)
|
|
|
+ Console.WriteLine($"Answer is : {sb.Distance}\nNano bots in range : {sb.NanoBots}");
|
|
|
+ }
|
|
|
+
|
|
|
+ private static SearchBox Resolve()
|
|
|
+ {
|
|
|
+ var bsize = (int)Math.Pow(2, 30);
|
|
|
+ var bcoord = -1 * bsize / 2;
|
|
|
+
|
|
|
+ List<SearchBox> SbQueue = new List<SearchBox> { new SearchBox(bsize, (bcoord, bcoord, bcoord)) };
|
|
|
+
|
|
|
+ while (true)
|
|
|
{
|
|
|
- Console.Clear();
|
|
|
- Console.WriteLine($"Testing with i = {i}");
|
|
|
+ SbQueue = SbQueue
|
|
|
+ .OrderByDescending(s => s.NanoBots)
|
|
|
+ .ThenBy(s => s.Distance)
|
|
|
+ .ThenBy(s => s.Size)
|
|
|
+ .ToList();
|
|
|
|
|
|
- (var manhattan, var nbest) = Test(nanoList, best, i);
|
|
|
- best = nbest;
|
|
|
- bestManhattant = manhattan;
|
|
|
- }
|
|
|
+ var first = SbQueue.First();
|
|
|
+
|
|
|
+ SbQueue.RemoveAt(0);
|
|
|
|
|
|
- Console.WriteLine($"\nAnswer is : {bestManhattant}");
|
|
|
+ if (first.Size == 1)
|
|
|
+ return first;
|
|
|
+
|
|
|
+ SbQueue.AddRange(first.Split());
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|