internal int DistanceTo(NanoBot otherBot) { int dist = Math.Abs(this.X - otherBot.X); dist += Math.Abs(this.Y - otherBot.Y); dist += Math.Abs(this.Z - otherBot.Z); return(dist); }
public Day23() : base(2018, 23) { Regex botParse = new Regex(".*?<(-?\\d+),(-?\\d+),(-?\\d+)>, r=(-?\\d+)"); foreach (var s in InputLines) { var match = botParse.Match(s); NanoBot bot = new NanoBot(); bot.X = int.Parse(match.Groups[1].Value); bot.Y = int.Parse(match.Groups[2].Value); bot.Z = int.Parse(match.Groups[3].Value); bot.R = int.Parse(match.Groups[4].Value); Bots.Add(bot); } }
/* Algorithm/explanation: https://www.reddit.com/r/adventofcode/comments/a8sqov/help_day_23_part_2_any_provably_correct_fast/ecfag7f */ internal override string SolvePart2() { PriorityQueue <NanoBot> q = new PriorityQueue <NanoBot>(); /* create a bot that has every other bot in range */ var maxRadius = Bots.Select(b => Math.Abs(b.X) + Math.Abs(b.Y) + Math.Abs(b.Z)).Max(); var searchBot = new NanoBot() { X = 0, Y = 0, Z = 0, R = maxRadius }; var intersectCount = Bots.Where(b => b.Intersects(searchBot)).Count(); q.AddOrUpdate(searchBot, intersectCount); while (q.Count > 0) { var maxPriority = q._priorities.Max(); searchBot = q._dataByPriority[maxPriority].OrderBy(d => d.DistanceTo(0, 0, 0)).OrderBy(d => d.R).First(); q.DequeueItem(searchBot); if (searchBot.R <= 0) { return(searchBot.DistanceTo(0, 0, 0).ToString()); } else { foreach (var bot in searchBot.SplitBot()) { intersectCount = Bots.Where(b => b.Intersects(bot)).Count(); q.AddOrUpdate(bot, intersectCount); } } } return("??"); }
internal bool Intersects(NanoBot otherBot) { return(DistanceTo(otherBot) <= R + otherBot.R); }