using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.RegularExpressions; namespace D23._2 { class Program { public class SearchBox { // 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) { Size = size; Coord = coord; } int? bots = null; public int NanoBots { get { if (bots.HasValue) return bots.Value; int count = 0; foreach (var (x, y, z, r) in nanoList) { int dist = RangedManhattan((x, y, z)); if (dist <= r) count++; } bots = count; return bots.Value; } } private int RangedManhattan((int x, int y, int z) coord) { int manhattan = 0; // 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; if (coord.y < Coord.y) manhattan += Coord.y - coord.y; if (coord.y > OpposedCoord.y) manhattan += coord.y - OpposedCoord.y; if (coord.z < Coord.z) manhattan += Coord.z - coord.z; if (coord.z > OpposedCoord.z) manhattan += coord.z - OpposedCoord.z; return manhattan; } 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 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; if (File.Exists(args[0]) == false) return; var file = File.OpenText(args[0]); var reg = new Regex(@"pos=<([\d-,]+)>, r=(\d+)"); 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(); var sb = Resolve(); 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 SbQueue = new List { new SearchBox(bsize, (bcoord, bcoord, bcoord)) }; while (true) { SbQueue = SbQueue .OrderByDescending(s => s.NanoBots) .ThenBy(s => s.Distance) .ThenBy(s => s.Size) .ToList(); var first = SbQueue.First(); SbQueue.RemoveAt(0); if (first.Size == 1) return first; SbQueue.AddRange(first.Split()); } } } }