| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- 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<SearchBox> SbQueue = new List<SearchBox> { 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());
- }
- }
- }
- }
|