From c25d7f1a016fbbc2abb5774e9fc80867cf8f5434 Mon Sep 17 00:00:00 2001 From: Ben Harris Date: Sat, 2 Jan 2021 19:31:06 -0500 Subject: [PATCH] day 20 part 1 --- aoc2020.test/DayTests.cs | 2 +- aoc2020/Day20.cs | 91 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 91 insertions(+), 2 deletions(-) diff --git a/aoc2020.test/DayTests.cs b/aoc2020.test/DayTests.cs index d7ea972..ce64713 100644 --- a/aoc2020.test/DayTests.cs +++ b/aoc2020.test/DayTests.cs @@ -27,7 +27,7 @@ namespace aoc2020.test // [DataRow(typeof(Day17), "293", "1816")] [DataRow(typeof(Day18), "12918250417632", "171259538712010")] [DataRow(typeof(Day19), "160", "357")] - [DataRow(typeof(Day20), "", "")] + [DataRow(typeof(Day20), "21599955909991", "")] [DataRow(typeof(Day21), "", "")] [DataRow(typeof(Day22), "", "")] [DataRow(typeof(Day23), "", "")] diff --git a/aoc2020/Day20.cs b/aoc2020/Day20.cs index 182fdd0..d6cb060 100644 --- a/aoc2020/Day20.cs +++ b/aoc2020/Day20.cs @@ -1,3 +1,7 @@ +using System; +using System.Collections.Generic; +using System.Linq; + namespace aoc2020 { /// @@ -5,18 +9,103 @@ namespace aoc2020 /// public sealed class Day20 : Day { + private readonly List _allPermutations; + private readonly List _topLefts; + public Day20() : base(20, "Jurassic Jigsaw") { + var lines = new List(); + var tiles = new List(); + var currentTileId = 0; + + foreach (var line in Input) + if (line.StartsWith("Tile ")) + { + currentTileId = int.Parse(line.Split(' ', ':')[1]); + } + else if (line == "") + { + tiles.Add(new(currentTileId, lines.Select(l => l.ToCharArray()).ToArray())); + lines.Clear(); + } + else + { + lines.Add(line); + } + + if (lines.Any()) tiles.Add(new(currentTileId, lines.Select(l => l.ToCharArray()).ToArray())); + + _allPermutations = tiles.SelectMany(t => t.AllPermutations()).ToList(); + _topLefts = _allPermutations + .Where(t => !_allPermutations.Any(t2 => t.TileId != t2.TileId && t.LeftId == t2.RightId) && + !_allPermutations.Any(t2 => t.TileId != t2.TileId && t.TopId == t2.BottomId)) + .ToList(); + } } public override string Part1() { - return ""; + return $"{_topLefts.Select(t => t.TileId).Distinct().Aggregate(1L, (acc, next) => acc * next)}"; } public override string Part2() { return ""; } + + private record Tile(int TileId, char[][] Pixels) + { + private const int Size = 10; + internal int TopId => GetId(z => (z, 0)); + internal int BottomId => GetId(z => (z, Size - 1)); + internal int LeftId => GetId(z => (0, z)); + internal int RightId => GetId(z => (Size - 1, z)); + + private int GetId(Func selector) + { + return Enumerable.Range(0, Size) + .Select(selector) + .Select((c, i) => (Pixels[c.x][c.y] == '#' ? 1 : 0) << i) + .Aggregate(0, (acc, next) => acc | next); + } + + private Tile RotateClockwise() + { + return Transform((x, y, newPixels) => newPixels[x][Size - 1 - y] = Pixels[y][x]); + } + + private Tile Flip() + { + return Transform((x, y, newPixels) => newPixels[y][Size - 1 - x] = Pixels[y][x]); + } + + private Tile Transform(Action transformFunc) + { + var newPixels = Enumerable.Repeat(false, Size).Select(_ => new char[Size]).ToArray(); + + for (var y = 0; y < Size; y++) + for (var x = 0; x < Size; x++) + transformFunc(x, y, newPixels); + + return new(TileId, newPixels); + } + + internal IEnumerable AllPermutations() + { + var tile = this; + for (var i = 1; i <= 8; i++) + { + yield return tile; + if (i == 4) tile = Flip(); + else if (i == 8) yield break; + tile = tile.RotateClockwise(); + } + } + + public string Format() + { + return $"Tile {TileId}:\n{string.Join("\n", Pixels.Select(p => new string(p)))}"; + } + } } } \ No newline at end of file