static void Main(string[] args)
        {
            JurassicJigsaw self = new JurassicJigsaw();

            self.readFile("./day20/day20.txt");
            self.parseFileContents();

            long prod = 1;

            for (int i = 0; i < self.tileList.Count; i++)
            {
                Tile tile = self.tileList[i];

                int[] edges = tile.findAllEdges();
                int   count = 0;
                for (int j = 0; j < self.tileList.Count(); j++)
                {
                    if (self.tileList[j].getTileNumber() != tile.getTileNumber())
                    {
                        int[] subedges = self.tileList[j].findAllEdges();
                        count += (int)edges.Intersect(subedges).Count();
                    }
                }

                // Tiles either have 4, 6 or 8 matching edges (because of rotation/flipping).
                // 4 Matching edges must mean they are corner tiles
                if (count == 4)
                {
                    prod *= (long)tile.getTileNumber();
                }
            }

            Console.WriteLine("Product of corner tiles: {0}", prod);
        }
        static void Main(string[] args)
        {
            JurassicJigsaw self = new JurassicJigsaw();

            self.readFile("./day20/day20.txt");
            self.parseFileContents();

            Tile[][] image = self.buildImage();
            FullImage fullImage = self.combineTiles(image);

            for (int i = 0; i < 10; i++) {
                fullImage.setTileState(i);
                int numberOfMonsters = fullImage.findMonsters();
                Console.WriteLine("{0} monsters found at state {1}", numberOfMonsters, i);
                if (numberOfMonsters > 0) {
                    int waterRoughness = fullImage.countWaterRoughness(numberOfMonsters);
                }
            }
        }