static long Part1(List <Tile> allTiles) { int imageSize = (int)Math.Sqrt(allTiles.Count); var visited = new bool[allTiles.Count]; var tiles = new TileContainer[imageSize, imageSize]; FindTileConfiguration(allTiles, visited, imageSize, 0, 0, tiles, 0); return((long)tiles[0, 0].Tile.Id * (long)tiles[imageSize - 1, 0].Tile.Id * (long)tiles[0, imageSize - 1].Tile.Id * (long)tiles[imageSize - 1, imageSize - 1].Tile.Id); }
static bool FindTileConfiguration(List <Tile> allTiles, bool[] visited, int imageSize, int currentY, int currentX, TileContainer[,] tiles, int count = 0, bool found = false) { if (found) { return(true); } if (count == imageSize * imageSize) { return(true); } for (int i = 0; i < allTiles.Count; i++) { if (!visited[allTiles[i].Index]) { for (int c = 0; c < 8; c++) { bool[,] puzzle = GetConfiguration(allTiles[i], c); if (IsConfigurationPossibleInPlace(tiles, currentX, currentY, puzzle.GetLength(0), puzzle)) { tiles[currentY, currentX] = new TileContainer() { Tile = allTiles[i], ConfigurationNumber = c, CurrentConfiguration = puzzle }; visited[i] = true; if (currentX < imageSize - 1) { found = FindTileConfiguration(allTiles, visited, imageSize, currentY, currentX + 1, tiles, count + 1, found); } else { found = FindTileConfiguration(allTiles, visited, imageSize, currentY + 1, 0, tiles, count + 1, found); } visited[i] = false; if (found) { return(found); } } } } } return(found); }
static long Part2(List <Tile> allTiles) { int imageSize = (int)Math.Sqrt(allTiles.Count); var visited = new bool[allTiles.Count]; var tiles = new TileContainer[imageSize, imageSize]; FindTileConfiguration(allTiles, visited, imageSize, 0, 0, tiles, 0); var image = PrepareImage(tiles, imageSize); var monster = LoadMonster(); var minRoughtness = int.MaxValue; for (int c = 0; c < 8; c++) { var imageConf = GetConfiguration(image, c); var roughtness = FindMonsters(imageConf, monster); if (roughtness < minRoughtness) { minRoughtness = roughtness; } } return(minRoughtness); }