using System; using System.Collections.Generic; using System.IO; namespace D18._2 { class Program { enum EnumType { Open = 0, Trees, Lumber } static void Main(string[] args) { if (args.Length < 1) return; if (File.Exists(args[0]) == false) return; var file = File.OpenText(args[0]); const int size = 50; var map = new (EnumType type, (int o, int t, int l) adj)[size, size]; CreateMap(file, map); (int o, int t, int l) count = (0, 0, 0); var prev = new Dictionary<(int, int, int), int>(); var dup = new Dictionary<(int, int, int), int>(); int minutes = 1; do { FillAdjacency(size, map); count = NextState(size, map); if (prev.TryGetValue(count, out int prevminute)) { if (dup.TryGetValue(count, out int dupminute)) { var period = minutes - prevminute; var leftover = minutes % period; if (minutes % period == 1_000_000_000 % period) { // this line seems not to make the schmilblick going forward // for (var i = 0; i < leftover; ++i) count = NextState(size, map); break; } } dup.TryAdd(count, minutes); } prev[count] = minutes; } while (minutes++ > 0); int result = count.l * count.t; Console.WriteLine($"The result is : {result}"); } private static (int o, int t, int l) NextState(int size, (EnumType type, (int o, int t, int l) adj)[,] map) { (int o, int t, int l) count = (0, 0, 0); for (var y = 0; y < size; ++y) { for (var x = 0; x < size; ++x) { var tile = map[y, x]; if (tile.type == EnumType.Open) { if (tile.adj.t >= 3) map[y, x].type = EnumType.Trees; } else if (tile.type == EnumType.Trees) { if (tile.adj.l >= 3) map[y, x].type = EnumType.Lumber; } else if (tile.type == EnumType.Lumber) { if (tile.adj.l >= 1 && tile.adj.t >= 1) map[y, x].type = EnumType.Lumber; else map[y, x].type = EnumType.Open; } if (map[y, x].type == EnumType.Open) count.o++; if (map[y, x].type == EnumType.Trees) count.t++; if (map[y, x].type == EnumType.Lumber) count.l++; } } return count; } private static (int o, int t, int l) FillAdjacency(int size, (EnumType type, (int o, int t, int l) adj)[,] map) { (int o, int t, int l) count = (0, 0, 0); for (var y = 0; y < size; ++y) for (var x = 0; x < size; ++x) { int count1 = OfType(EnumType.Open, size, map, y, x); int count2 = OfType(EnumType.Trees, size, map, y, x); int count3 = OfType(EnumType.Lumber, size, map, y, x); var result = (count1, count2, count3); map[y, x].adj = result; if (map[y, x].type == EnumType.Open) count.o++; if (map[y, x].type == EnumType.Trees) count.t++; if (map[y, x].type == EnumType.Lumber) count.l++; } return count; } private static int OfType(EnumType type, int size, (EnumType type, (int o, int t, int l) adj)[,] map, int y, int x) { int count = 0; if (y > 0 && x > 0) count += map[y - 1, x - 1].type == type ? 1 : 0; if (y > 0) count += map[y - 1, x].type == type ? 1 : 0; if (y > 0 && x < size - 1) count += map[y - 1, x + 1].type == type ? 1 : 0; if (x > 0) count += map[y, x - 1].type == type ? 1 : 0; if (x < size - 1) count += map[y, x + 1].type == type ? 1 : 0; if (y < size - 1 && x > 0) count += map[y + 1, x - 1].type == type ? 1 : 0; if (y < size - 1) count += map[y + 1, x].type == type ? 1 : 0; if (y < size - 1 && x < size - 1) count += map[y + 1, x + 1].type == type ? 1 : 0; return count; } private static void CreateMap(StreamReader file, (EnumType type, (int o, int t, int l) adj)[,] map) { int y = 0; do { var line = file.ReadLine(); if (line == null) break; int x = 0; foreach (var c in line) { EnumType type; switch (c) { case '|': type = EnumType.Trees; break; case '#': type = EnumType.Lumber; break; case '.': default: type = EnumType.Open; break; } map[y, x] = (type, (0, 0, 0)); x++; } ++y; } while (true); } } }