Пример #1
0
 public void AlignToOther(Direction dir, MapTile other)
 {
     isAligned          = true;
     adjecentTiles[dir] = other;
 }
Пример #2
0
        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}");
        }