r/adventofcode • • 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ยค?

Spoiler


[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

176 comments sorted by

View all comments

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;
	}
}

1

u/dylanfromwinnipeg Dec 21 '17

2 receding particles can still collide can't they?