--- Day 9: Tiling problem ---

December 9

Listening to: PlayStation downtempo mix


I've fallen a few days behind now - the puzzle for the 11th comes out in a few minutes. But I've been busy the past few days, and I haven't felt any pressure about "falling behind" this year. I'm kinda looking forward to it finishing a bit early. Then again, I'm considering checking out past years to see how it is. I've heard that 2019 is a particularly fun year!


I think I can predict part 2 based on this part 1, but at least for part 1, it seems simple enough:

For each pair of coordinates, find the rectangle with the biggest area.

long width = Math.Abs(Tiles[i].X - Tiles[j].X) + 1;
long height = Math.Abs(Tiles[i].Y - Tiles[j].Y) + 1;

largest = Math.Max(largest, width * height);

This one isn't quite what I was expecting; now, I can only look for rectangles that are within an area defined by the pattern of tiles provided.

The area is too large (100,000 per side) to just an array of bools of "in" tiles; that would be 1.25gb assuming it's a bit array. Looking at my input again though, I noticed that the lines are in adjacent pairs. In the example:

9,7
9,5
2,5
2,3

Notice how the first two lines have 9 for the X, and the next two have 2? And for the Y, the middle two are 5? I think the easier answer for this one might simply be: What is the largest rectangle that does not contain a red tile?

private bool ContainsRedTile(Point a, Point b)
{
    var xMin = Math.Min(a.X, b.X);
    var xMax = Math.Max(a.X, b.X);
    var yMin = Math.Min(a.Y, b.Y);
    var yMax = Math.Max(a.Y, b.Y);

    foreach (var tile in Tiles)
    {
        if (Equals(tile, a) || Equals(tile, b)) { continue; }

        if (tile.X > xMin && tile.X < xMax &&
            tile.Y > yMin && tile.Y < yMax)
        {
            return true;
        }
    }

    return false;
}

That doesn't work. The problem is that a red tile can be on the border, but then the next line segment goes out of the rectangle. There's no good way by just looking at the individual red tiles which way the line segment is going.

What I need to be doing is looking at line segments. Or, more accurately, Intersecting Boxes; more specifically an AABB collision. As these are all axis-aligned, it's easy enough to just check the corners of the box being tested and the edge (which is a box with width or length 1) and seeing if there's an intersection.

// Code simplified from actual submission code
private bool HasIntersection(Point a, Point b)
{
    int minX = Math.Min(a.X, b.X); int maxX = Math.Max(a.X, b.X);
    int minY = Math.Min(a.Y, b.Y); int maxY = Math.Max(a.Y, b.Y);

    for (int i = 0; i < Tiles.Count; i++)
    {
        var c = Tiles[i];
        var d = Tiles[i+1];

        int eMinX = Math.Min(c.X, d.X); int eMaxX = Math.Max(c.X, d.X);
        int eMinY = Math.Min(c.Y, d.Y); int eMaxY = Math.Max(c.Y, d.Y);

        if (minX < eMaxX && maxX > eMinX && minY < eMaxY && maxY > eMinY)
        {
            return true;
        }
    }

    return false;
}
```a

Time taken: 1 hour 30 minutes

My solutions for today's puzzles