Program.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. namespace D18._2
  5. {
  6. class Program
  7. {
  8. enum EnumType { Open = 0, Trees, Lumber }
  9. static void Main(string[] args)
  10. {
  11. if (args.Length < 1) return;
  12. if (File.Exists(args[0]) == false) return;
  13. var file = File.OpenText(args[0]);
  14. const int size = 50;
  15. var map = new (EnumType type, (int o, int t, int l) adj)[size, size];
  16. CreateMap(file, map);
  17. (int o, int t, int l) count = (0, 0, 0);
  18. var prev = new Dictionary<(int, int, int), int>();
  19. var dup = new Dictionary<(int, int, int), int>();
  20. int minutes = 1;
  21. do
  22. {
  23. FillAdjacency(size, map);
  24. count = NextState(size, map);
  25. if (prev.TryGetValue(count, out int prevminute))
  26. {
  27. if (dup.TryGetValue(count, out int dupminute))
  28. {
  29. var period = minutes - prevminute;
  30. var leftover = minutes % period;
  31. if (minutes % period == 1_000_000_000 % period)
  32. {
  33. // this line seems not to make the schmilblick going forward
  34. // for (var i = 0; i < leftover; ++i) count = NextState(size, map);
  35. break;
  36. }
  37. }
  38. dup.TryAdd(count, minutes);
  39. }
  40. prev[count] = minutes;
  41. } while (minutes++ > 0);
  42. int result = count.l * count.t;
  43. Console.WriteLine($"The result is : {result}");
  44. }
  45. private static (int o, int t, int l) NextState(int size, (EnumType type, (int o, int t, int l) adj)[,] map)
  46. {
  47. (int o, int t, int l) count = (0, 0, 0);
  48. for (var y = 0; y < size; ++y)
  49. {
  50. for (var x = 0; x < size; ++x)
  51. {
  52. var tile = map[y, x];
  53. if (tile.type == EnumType.Open)
  54. {
  55. if (tile.adj.t >= 3) map[y, x].type = EnumType.Trees;
  56. }
  57. else if (tile.type == EnumType.Trees)
  58. {
  59. if (tile.adj.l >= 3) map[y, x].type = EnumType.Lumber;
  60. }
  61. else if (tile.type == EnumType.Lumber)
  62. {
  63. if (tile.adj.l >= 1 && tile.adj.t >= 1) map[y, x].type = EnumType.Lumber;
  64. else map[y, x].type = EnumType.Open;
  65. }
  66. if (map[y, x].type == EnumType.Open) count.o++;
  67. if (map[y, x].type == EnumType.Trees) count.t++;
  68. if (map[y, x].type == EnumType.Lumber) count.l++;
  69. }
  70. }
  71. return count;
  72. }
  73. private static (int o, int t, int l) FillAdjacency(int size, (EnumType type, (int o, int t, int l) adj)[,] map)
  74. {
  75. (int o, int t, int l) count = (0, 0, 0);
  76. for (var y = 0; y < size; ++y)
  77. for (var x = 0; x < size; ++x)
  78. {
  79. int count1 = OfType(EnumType.Open, size, map, y, x);
  80. int count2 = OfType(EnumType.Trees, size, map, y, x);
  81. int count3 = OfType(EnumType.Lumber, size, map, y, x);
  82. var result = (count1, count2, count3);
  83. map[y, x].adj = result;
  84. if (map[y, x].type == EnumType.Open) count.o++;
  85. if (map[y, x].type == EnumType.Trees) count.t++;
  86. if (map[y, x].type == EnumType.Lumber) count.l++;
  87. }
  88. return count;
  89. }
  90. private static int OfType(EnumType type, int size, (EnumType type, (int o, int t, int l) adj)[,] map, int y, int x)
  91. {
  92. int count = 0;
  93. if (y > 0 && x > 0) count += map[y - 1, x - 1].type == type ? 1 : 0;
  94. if (y > 0) count += map[y - 1, x].type == type ? 1 : 0;
  95. if (y > 0 && x < size - 1) count += map[y - 1, x + 1].type == type ? 1 : 0;
  96. if (x > 0) count += map[y, x - 1].type == type ? 1 : 0;
  97. if (x < size - 1) count += map[y, x + 1].type == type ? 1 : 0;
  98. if (y < size - 1 && x > 0) count += map[y + 1, x - 1].type == type ? 1 : 0;
  99. if (y < size - 1) count += map[y + 1, x].type == type ? 1 : 0;
  100. if (y < size - 1 && x < size - 1) count += map[y + 1, x + 1].type == type ? 1 : 0;
  101. return count;
  102. }
  103. private static void CreateMap(StreamReader file, (EnumType type, (int o, int t, int l) adj)[,] map)
  104. {
  105. int y = 0;
  106. do
  107. {
  108. var line = file.ReadLine();
  109. if (line == null) break;
  110. int x = 0;
  111. foreach (var c in line)
  112. {
  113. EnumType type;
  114. switch (c)
  115. {
  116. case '|':
  117. type = EnumType.Trees;
  118. break;
  119. case '#':
  120. type = EnumType.Lumber;
  121. break;
  122. case '.':
  123. default:
  124. type = EnumType.Open;
  125. break;
  126. }
  127. map[y, x] = (type, (0, 0, 0));
  128. x++;
  129. }
  130. ++y;
  131. } while (true);
  132. }
  133. }
  134. }