01020304050607080910111213141516171819202122232425

Advent of Code

2020/24

Lobby Layout

in C#

by encse

Your raft makes it to the tropical island; it turns out that the small crab was an excellent navigator. You make your way to the resort.

As you enter the lobby, you discover a small problem: the floor is being renovated. You can't even reach the check-in desk until they've finished installing the new tile floor.

Read the full puzzle.

using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;

namespace AdventOfCode.Y2020.Day24;

record Tile(int x, int y);

[ProblemName("Lobby Layout")]
class Solution : Solver {

    public object PartOne(string input) => ParseBlackTiles(input).Count();

    public object PartTwo(string input) =>
        Enumerable.Range(0, 100)
            .Aggregate(ParseBlackTiles(input), (blackTiles, _) => Flip(blackTiles))
            .Count();

    Dictionary<string, (int x, int y)> HexDirections = new Dictionary<string, (int x, int y)> {
        {"o",  ( 0,  0)},
        {"ne", ( 1,  1)},
        {"nw", (-1,  1)},
        {"e",  ( 2,  0)},
        {"w",  (-2,  0)},
        {"se", ( 1, -1)},
        {"sw", (-1, -1)},
    };

    IEnumerable<Tile> Neighbourhood(Tile tile) =>
        from dir in HexDirections.Values select new Tile(tile.x + dir.x, tile.y + dir.y);

    HashSet<Tile> Flip(HashSet<Tile> blackTiles) {
        var tiles = (
            from black in blackTiles
            from tile in Neighbourhood(black)
            select tile
        ).ToHashSet();

        return (
            from tile in tiles
            let blacks = Neighbourhood(tile).Count(n => blackTiles.Contains(n))
            where blacks == 2 || blacks == 3 && blackTiles.Contains(tile)
            select tile
        ).ToHashSet();
    }

    HashSet<Tile> ParseBlackTiles(string input) {
        var tiles = new Dictionary<Tile, bool>();

        foreach (var line in input.Split("\n")) {
            var tile = Walk(line);
            tiles[tile] = !tiles.GetValueOrDefault(tile);
        }

        return (from kvp in tiles where kvp.Value select kvp.Key).ToHashSet();
    }

    Tile Walk(string line) {
        var (x, y) = (0, 0);
        while (line != "") {
            foreach (var kvp in HexDirections) {
                if (line.StartsWith(kvp.Key)) {
                    line = line.Substring(kvp.Key.Length);
                    (x, y) = (x + kvp.Value.x, y + kvp.Value.y);
                }
            }
        }
        return new Tile(x, y);
    }
}

Please ☆ my repo if you like it!

© 2025 Advent of Code is a registered trademark in the US Images provided by Bing image creator