--- Day 7: Junction Boxes ---

December 7

Listening to: Vinesauce


Looks like today is the first 3d problem.

This one doesn't seem like too big of a deal I guess. My basic thought for what to do is:

  1. Put each box into a "Circuit" (list)
  2. Test every pair of circuits
  3. Merge the two circuits with the shortest distance junction boxes
  4. Repeat # of times needed
for (int iteration = 0; iteration < 10; iteration++)
{
    double minDistance = double.MaxValue;
    int toMerge1 = -1, toMerge2 = -1;

    for (int i = 0; i < Circuits.Count; i++)
    {
        for (int j = i + 1; j < Circuits.Count; j++)
        {
            var distance = GetCircuitDistance(Circuits[i], Circuits[j]);
            if (distance < minDistance)
            {
                minDistance = distance;
                toMerge1 = i;
                toMerge2 = j;
            }
        }
    }

    var newList = Circuits[toMerge1].Concat(Circuits[toMerge2]).ToList();
    Circuits.RemoveAt(toMerge2);
    Circuits.RemoveAt(toMerge1);
    Circuits.Add(newList);
}

... except that this isn't what the prompt was asking for. It was asking to connect ones even if they're already connected. Whoops.

Okay. Instead, just find the distance between each pair of boxes, then sorting by the minimum distance, merge those together.

var distances = new List<(double, int, int)>();
for (int i = 0; i < Boxes.Count; i++)
{
    for (int j = i + 1; j < Boxes.Count; j++)
    {
        distances.Add((Boxes[i].DistanceFrom(Boxes[j]), i, j));
    }
}

var byShortest = distances.OrderBy(d => d.Item1).Take(10);

foreach (var boxPair in byShortest)
{
    int left = Circuits.FindIndex(c => c.Contains(Boxes[boxPair.Item2]));
    int right = Circuits.FindIndex(c => c.Contains(Boxes[boxPair.Item3]));

    if (left != right)
    {
        var newList = Circuits[left].Concat(Circuits[right]).ToList();
        Circuits.RemoveAt(Math.Max(left, right));
        Circuits.RemoveAt(Math.Min(left, right));
        Circuits.Add(newList);
    }
}

Then the return value is just some linq...

return Circuits.Select(c => c.Count)
    .OrderBy(c => c)
    .Reverse()
    .Take(3)
    .Aggregate(1, (a, v) => a * v);

Neat!


Okay, this next one shouldn't be more difficult. For the second half of part one, instead of just taking a limited amount, keep going until they are all connected; the real work is done quickly enough.

if (Circuits.Count == 1)
{
    return Boxes[boxPair.Item2].X * Boxes[boxPair.Item3].X;
}

Time taken: 1 hour

My solutions for today's puzzles