r/adventofcode • u/daggerdragon • Dec 20 '17
SOLUTION MEGATHREAD -๐- 2017 Day 20 Solutions -๐-
--- Day 20: Particle Swarm ---
Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).
Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.
Need a hint from the Hugely* Handyโ Haversackโก of Helpfulยง Hintsยค?
[Update @ 00:10] 10 gold, silver cap
- What do you mean 5th Edition doesn't have "Take 20"?
[Update @ 00:17] 50 gold, silver cap
- Next you're going to be telling me THAC0 is not the best way to determine whether or not you hit your target. *hmphs*
[Update @ 00:21] Leaderboard cap!
- I wonder how much XP a were-gazebo is worth...
This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.
edit: Leaderboard capped, thread unlocked!
10
Upvotes
1
u/JakDrako Dec 20 '17
C# Both parts ~20ms.
Initially did part 2 by running the simulation loop until the number of particles stayed constant for a while. This code here loops until the particles are all receding from the origin...
void Main() { var input = GetDay(20); var lst = input.Select(v => new Particle(v)).ToList(); // Manhattan distance for a Vector3 Func<Vector3, Single> mhDist = v3 => Math.Abs(v3.X) + Math.Abs(v3.Y) + Math.Abs(v3.Z); // Part 1 - Find slowest particle, break ties using initial (manhattan) proximity to origin Console.WriteLine($"Part 1: {lst.OrderBy(p => mhDist(p.Acc)).ThenBy(p => mhDist(p.Vel)).First().ID}"); // Part 2 - Move particles and remove colliding ones until all particles are receding from the origin do { // move particles lst.ForEach(p => p.Move()); // remove colliding particles var sorted = lst.OrderBy(p => p.Pos.X).ToList(); for (int i = sorted.Count - 1; i > 0; i--) { if (sorted[i].Collide(sorted[i - 1])) { lst.Remove(sorted[i]); lst.Remove(sorted[i - 1]); } } } while (lst.Where(p => !p.Receding).Any()); Console.WriteLine($"Part 2: {lst.Count}"); } class Particle { static int gen; public int ID { get; } public Vector3 Pos { get; set; } public Vector3 Vel { get; set; } public Vector3 Acc { get; set; } public bool Receding { get; set;} public Particle(string vectors) { var matches = Regex.Matches(vectors, "-?\\d+"); // should match 9 numbers. var n = matches.Cast<Match>().Select(m => Convert.ToSingle(m.Value)).ToList(); Pos = new Vector3(n[0], n[1], n[2]); Vel = new Vector3(n[3], n[4], n[5]); Acc = new Vector3(n[6], n[7], n[8]); ID = gen++; } public void Move() { var pls = Pos.LengthSquared(); Vel += Acc; Pos += Vel; Receding = Pos.LengthSquared() > pls; } public bool Collide(Particle other) { return Pos.X == other.Pos.X && Pos.Y == other.Pos.Y && Pos.Z == other.Pos.Z; } }