public void AlignToOther(Direction dir, MapTile other) { isAligned = true; adjecentTiles[dir] = other; }
public override void Solve() { StreamReader sr = new StreamReader("Inputs/day20.txt"); MapTile t = null; int index = 0; while (!sr.EndOfStream) { string line = sr.ReadLine(); if (line.Contains("Tile")) { if (t != null) { allTiles.Add(t); } t = new MapTile(); t.tileId = int.Parse(Regex.Match(line, @"\d+").Value); index = 0; } else { for (int i = 0; i < line.Length; i++) { if (line[i] == '.' || line[i] == '#') { t.pixels[index, i] = line[i]; } } index++; } } allTiles.Add(t); /*PrintTile(allTiles[0]); * Console.WriteLine(""); * allTiles[0].Rotate(true); * PrintTile(allTiles[0]); * allTiles[0].Rotate(false); * Console.WriteLine(""); * PrintTile(allTiles[0]);*/ List <MapTile> freeTiles = new List <MapTile>(allTiles); Queue <MapTile> toCheck = new Queue <MapTile>(); freeTiles[0].x = 0; freeTiles[0].y = 0; toCheck.Enqueue(freeTiles[0]); while (toCheck.Count > 0) { MapTile currentTile = toCheck.Dequeue(); //freeTiles.Remove(currentTile); foreach (MapTile.Direction dir in currentTile.adjecentTiles.Keys.ToList()) { if (currentTile.adjecentTiles[dir] != null) { continue; } char[] edgeRow = currentTile.GetEdgeRowByDirection(dir); foreach (MapTile otherTile in freeTiles) { bool isAligning = false; for (int flip = 0; flip <= 3; flip++) //0=no flip, 1=flipx, 2=flipy, 3=flipxy { //MapTile copy = new MapTile(otherTile); if (flip == 1) { otherTile.Flip(true); } else if (flip == 2) { otherTile.Flip(false); } else if (flip == 3) { otherTile.Flip(true); otherTile.Flip(false); } for (int rot = 0; rot <= 4; rot++) { MapTile.Direction otherDir = (MapTile.Direction)((((int)dir) + 2) % 4); char[] otherRow = otherTile.GetEdgeRowByDirection(otherDir); if (MapTile.AreRowsEqual(edgeRow, otherRow)) { isAligning = true; break; } otherTile.Rotate(true); } if (isAligning) { break; } } if (isAligning) { currentTile.adjecentTiles[dir] = otherTile; otherTile.adjecentTiles[(MapTile.Direction)((((int)dir) + 2) % 4)] = currentTile; freeTiles.Remove(otherTile); toCheck.Enqueue(otherTile); switch (dir) { case MapTile.Direction.Top: otherTile.y = currentTile.y - 1; otherTile.x = currentTile.x; break; case MapTile.Direction.Right: otherTile.x = currentTile.x + 1; otherTile.y = currentTile.y; break; case MapTile.Direction.Bottom: otherTile.y = currentTile.y + 1; otherTile.x = currentTile.x; break; case MapTile.Direction.Left: otherTile.x = currentTile.x - 1; otherTile.y = currentTile.y; break; } break; } } } if (currentTile.adjecentTiles.Count(x => x.Value == null) >= 3) { freeTiles.Add(currentTile); } } //PrintMap(); int minY = allTiles.Min(x => x.y); int minX = allTiles.Min(x => x.x); int maxY = allTiles.Max(x => x.y); int maxX = allTiles.Max(x => x.x); ulong p1 = (ulong)allTiles.First(x => x.x == minX && x.y == minY).tileId * (ulong)allTiles.First(x => x.x == minX && x.y == maxY).tileId * (ulong)allTiles.First(x => x.x == maxX && x.y == minY).tileId * (ulong)allTiles.First(x => x.x == maxX && x.y == maxY).tileId; Console.WriteLine($"Part 1: {p1}"); MapTile fullMap = new MapTile(); fullMap.pixels = new char[(MapTile.tileSize - 2) * (int)Math.Sqrt(allTiles.Count), (MapTile.tileSize - 2) * (int)Math.Sqrt(allTiles.Count)]; List <MapTile> orderedTiles = allTiles.OrderBy(x => x.x).OrderBy(x => x.y).ToList(); int lastY = 0; int lastX = 0; foreach (MapTile mt in allTiles) { mt.RemoveBorders(); mt.y -= minY; mt.x -= minX; } //PrintMap(); for (int i = 0; i < orderedTiles.Count; i++) { if (orderedTiles[i].y != lastY) { lastY = orderedTiles[i].y; } if (orderedTiles[i].x != lastX) { lastX = orderedTiles[i].x; } for (int j = 0; j < orderedTiles[i].pixels.GetLength(0); j++) { for (int l = 0; l < orderedTiles[i].pixels.GetLength(1); l++) { int yindx = lastY * (orderedTiles[i].pixels.GetLength(0)) + j; int xindx = lastX * (orderedTiles[i].pixels.GetLength(1)) + l; fullMap.pixels[yindx, xindx] = orderedTiles[i].pixels[j, l]; } } } //example map is rotated once right and flipped by x MapTile.tileSize = fullMap.pixels.GetLength(0); //fullMap.Rotate(true); //fullMap.Flip(true); CreateMonsterTemplate(); int monsterCount = 0; int roughness = 0; bool monsterFound = false; for (int flip = 0; flip < 4; flip++) { if (monsterFound) { break; } if (flip == 1) { fullMap.Flip(true); } else if (flip == 2) { fullMap.Flip(false); } else if (flip == 3) { fullMap.Flip(true); fullMap.Flip(false); } for (int r = 0; r <= 4; r++) { if (monsterFound) { break; } fullMap.Rotate(true); roughness = 0; for (int y = 0; y < fullMap.pixels.GetLength(0); y++) { for (int x = 0; x < fullMap.pixels.GetLength(1); x++) { if (fullMap.pixels[y, x] == '#') { List <Tuple <int, int> > monsterPixels = IsMonster(fullMap, x, y); if (monsterPixels != null) { monsterFound = true; monsterCount++; foreach (Tuple <int, int> mp in monsterPixels) { fullMap.pixels[mp.Item1, mp.Item2] = 'O'; } } else { roughness++; } } } } } } PrintMap(fullMap); Console.WriteLine($"Part 2: Monster count: {monsterCount}, roughness = {roughness}"); }