Equd

AOC 2020 Day 17

Dec 17th, 2020
1,065
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.56 KB | None | 0 0
  1. #load "xunit"
  2. #load "..\AOC Connector"
  3.  
  4. void Main(string[] args)
  5. {
  6.     if(args == null)
  7.         RunTests();  // Call RunTests() or press Alt+Shift+T to initiate testing.
  8.  
  9.     //get aoc data
  10.     var aoc = new AdventOfCode(2020, 17);
  11.    
  12.     //solve A
  13.     aoc.SubmitAnswer(SolveA(aoc.InputLines), Part.A);
  14.  
  15.     //solve B
  16.     aoc.SubmitAnswer(SolveB(aoc.InputLines), Part.B);
  17. }
  18.  
  19. abstract class ConwayDimension<T>
  20. {  
  21.     protected static int[] dirs = new[] { -1, 0, 1 };
  22.     protected Dictionary<T, bool> d1 = new Dictionary<T, bool>();
  23.     protected Dictionary<T, bool> d2 = new Dictionary<T, bool>();
  24.    
  25.     public int Solve(string[] data)
  26.     {
  27.         //fill the dictionary
  28.         for (int i = 0; i < data.Length; i++)
  29.         {
  30.             for (int j = 0; j < data[i].Length; j++)
  31.             {
  32.                 //create location
  33.                 var loc = CreateItem(i, j);
  34.                 d1[loc] = data[i][j] == '#';
  35.  
  36.                 //add the neighbourds of this point
  37.                 foreach (var nb in GetNeighbours(loc))
  38.                 {
  39.                     //might be overwritten again.
  40.                     if (d1.ContainsKey(nb) == false) d1[nb] = false;
  41.                 }
  42.  
  43.             }
  44.         }
  45.  
  46.         //execute the cycles
  47.         for (int cycles = 0; cycles < 6; cycles++)
  48.         {
  49.             //check all point in the dictionary
  50.             foreach (var point in d1)
  51.             {
  52.                 //get all the neighbourss
  53.                 var pointNeighbours = GetNeighbours(point.Key).ToArray();
  54.                
  55.                 //count the actives
  56.                 var count = pointNeighbours.Count(x => d1.TryGetValue(x, out bool b) && b);
  57.                
  58.                 //should this point be active?
  59.                 bool active = point.Value
  60.                     ? count is 2 or 3
  61.                     : count is 3;
  62.                
  63.                 //store result
  64.                 d2[point.Key] = active;
  65.  
  66.                 //add the neighbours for the next cycle
  67.                 if (count != 0)
  68.                 {
  69.                     foreach (var nb in pointNeighbours)
  70.                     {
  71.                         //only write empty cells
  72.                         if (d2.ContainsKey(nb) == false) d2[nb] = false;
  73.                     }
  74.                 }
  75.             }
  76.            
  77.             d1 = d2;
  78.             d2 = new Dictionary<T, bool>();
  79.         }
  80.  
  81.         return d1.Values.Count(x => x);
  82.  
  83.     }
  84.  
  85.     protected abstract T CreateItem(int i, int j);
  86.        
  87.     protected abstract IEnumerable<T> GetNeighbours(T loc);
  88. }
  89.  
  90. class Conway3D : ConwayDimension<(int x, int y, int z)>
  91. {
  92.     protected override (int x, int y, int z) CreateItem(int i, int j) => (i,j,0);
  93.  
  94.     protected override IEnumerable<(int x, int y, int z)> GetNeighbours((int x, int y, int z) loc)
  95.     {      
  96.         /*
  97.         foreach (var a in dirs)
  98.         foreach (var b in dirs)
  99.         foreach (var c in dirs)
  100.         {
  101.             if (a == 0 && b == 0 && c == 0) continue;
  102.             yield return (loc.x + a, loc.y + b, loc.z + c);
  103.         }
  104.         */
  105.        
  106.         //13ms -> 11ms
  107.         return new []
  108.         {
  109.             (loc.x + -1, loc.y + -1, loc.z + -1),
  110.             (loc.x + -1, loc.y + -1, loc.z + 0),
  111.             (loc.x + -1, loc.y + -1, loc.z + 1),
  112.             (loc.x + -1, loc.y + 0, loc.z + -1),
  113.             (loc.x + -1, loc.y + 0, loc.z + 0),
  114.             (loc.x + -1, loc.y + 0, loc.z + 1),
  115.             (loc.x + -1, loc.y + 1, loc.z + -1),
  116.             (loc.x + -1, loc.y + 1, loc.z + 0),
  117.             (loc.x + -1, loc.y + 1, loc.z + 1),
  118.             (loc.x + 0, loc.y + -1, loc.z + -1),
  119.             (loc.x + 0, loc.y + -1, loc.z + 0),
  120.             (loc.x + 0, loc.y + -1, loc.z + 1),
  121.             (loc.x + 0, loc.y + 0, loc.z + -1),
  122.             (loc.x + 0, loc.y + 0, loc.z + 1),
  123.             (loc.x + 0, loc.y + 1, loc.z + -1),
  124.             (loc.x + 0, loc.y + 1, loc.z + 0),
  125.             (loc.x + 0, loc.y + 1, loc.z + 1),
  126.             (loc.x + 1, loc.y + -1, loc.z + -1),
  127.             (loc.x + 1, loc.y + -1, loc.z + 0),
  128.             (loc.x + 1, loc.y + -1, loc.z + 1),
  129.             (loc.x + 1, loc.y + 0, loc.z + -1),
  130.             (loc.x + 1, loc.y + 0, loc.z + 0),
  131.             (loc.x + 1, loc.y + 0, loc.z + 1),
  132.             (loc.x + 1, loc.y + 1, loc.z + -1),
  133.             (loc.x + 1, loc.y + 1, loc.z + 0),
  134.             (loc.x + 1, loc.y + 1, loc.z + 1),
  135.         };
  136.     }
  137. }
  138. class Conway4D : ConwayDimension<(int x, int y, int z, int w)>
  139. {
  140.     protected override (int x, int y, int z, int w) CreateItem(int i, int j) => (i, j, 0, 0);
  141.  
  142.     protected override IEnumerable<(int x, int y, int z, int w)> GetNeighbours((int x, int y, int z, int w) loc)
  143.     {
  144.         //foreach (var a in dirs)
  145.         //foreach (var b in dirs)
  146.         //foreach (var c in dirs)
  147.         //foreach (var d in dirs)
  148.         //{
  149.         //  if (a == 0 && b == 0 && c == 0 && d == 0) continue;
  150.         //  yield return (loc.x + a, loc.y + b, loc.z + c, loc.w + d);
  151.         //}
  152.        
  153.         //optimize 450ms vs 385ms
  154.         return new[]
  155.         {
  156.             (loc.x + -1, loc.y + -1, loc.z + -1, loc.w + -1),
  157.             (loc.x + -1, loc.y + -1, loc.z + -1, loc.w + 0),
  158.             (loc.x + -1, loc.y + -1, loc.z + -1, loc.w + 1),
  159.             (loc.x + -1, loc.y + -1, loc.z + 0, loc.w + -1),
  160.             (loc.x + -1, loc.y + -1, loc.z + 0, loc.w + 0),
  161.             (loc.x + -1, loc.y + -1, loc.z + 0, loc.w + 1),
  162.             (loc.x + -1, loc.y + -1, loc.z + 1, loc.w + -1),
  163.             (loc.x + -1, loc.y + -1, loc.z + 1, loc.w + 0),
  164.             (loc.x + -1, loc.y + -1, loc.z + 1, loc.w + 1),
  165.             (loc.x + -1, loc.y + 0, loc.z + -1, loc.w + -1),
  166.             (loc.x + -1, loc.y + 0, loc.z + -1, loc.w + 0),
  167.             (loc.x + -1, loc.y + 0, loc.z + -1, loc.w + 1),
  168.             (loc.x + -1, loc.y + 0, loc.z + 0, loc.w + -1),
  169.             (loc.x + -1, loc.y + 0, loc.z + 0, loc.w + 0),
  170.             (loc.x + -1, loc.y + 0, loc.z + 0, loc.w + 1),
  171.             (loc.x + -1, loc.y + 0, loc.z + 1, loc.w + -1),
  172.             (loc.x + -1, loc.y + 0, loc.z + 1, loc.w + 0),
  173.             (loc.x + -1, loc.y + 0, loc.z + 1, loc.w + 1),
  174.             (loc.x + -1, loc.y + 1, loc.z + -1, loc.w + -1),
  175.             (loc.x + -1, loc.y + 1, loc.z + -1, loc.w + 0),
  176.             (loc.x + -1, loc.y + 1, loc.z + -1, loc.w + 1),
  177.             (loc.x + -1, loc.y + 1, loc.z + 0, loc.w + -1),
  178.             (loc.x + -1, loc.y + 1, loc.z + 0, loc.w + 0),
  179.             (loc.x + -1, loc.y + 1, loc.z + 0, loc.w + 1),
  180.             (loc.x + -1, loc.y + 1, loc.z + 1, loc.w + -1),
  181.             (loc.x + -1, loc.y + 1, loc.z + 1, loc.w + 0),
  182.             (loc.x + -1, loc.y + 1, loc.z + 1, loc.w + 1),
  183.             (loc.x + 0, loc.y + -1, loc.z + -1, loc.w + -1),
  184.             (loc.x + 0, loc.y + -1, loc.z + -1, loc.w + 0),
  185.             (loc.x + 0, loc.y + -1, loc.z + -1, loc.w + 1),
  186.             (loc.x + 0, loc.y + -1, loc.z + 0, loc.w + -1),
  187.             (loc.x + 0, loc.y + -1, loc.z + 0, loc.w + 0),
  188.             (loc.x + 0, loc.y + -1, loc.z + 0, loc.w + 1),
  189.             (loc.x + 0, loc.y + -1, loc.z + 1, loc.w + -1),
  190.             (loc.x + 0, loc.y + -1, loc.z + 1, loc.w + 0),
  191.             (loc.x + 0, loc.y + -1, loc.z + 1, loc.w + 1),
  192.             (loc.x + 0, loc.y + 0, loc.z + -1, loc.w + -1),
  193.             (loc.x + 0, loc.y + 0, loc.z + -1, loc.w + 0),
  194.             (loc.x + 0, loc.y + 0, loc.z + -1, loc.w + 1),
  195.             (loc.x + 0, loc.y + 0, loc.z + 0, loc.w + -1),
  196.             (loc.x + 0, loc.y + 0, loc.z + 0, loc.w + 1),
  197.             (loc.x + 0, loc.y + 0, loc.z + 1, loc.w + -1),
  198.             (loc.x + 0, loc.y + 0, loc.z + 1, loc.w + 0),
  199.             (loc.x + 0, loc.y + 0, loc.z + 1, loc.w + 1),
  200.             (loc.x + 0, loc.y + 1, loc.z + -1, loc.w + -1),
  201.             (loc.x + 0, loc.y + 1, loc.z + -1, loc.w + 0),
  202.             (loc.x + 0, loc.y + 1, loc.z + -1, loc.w + 1),
  203.             (loc.x + 0, loc.y + 1, loc.z + 0, loc.w + -1),
  204.             (loc.x + 0, loc.y + 1, loc.z + 0, loc.w + 0),
  205.             (loc.x + 0, loc.y + 1, loc.z + 0, loc.w + 1),
  206.             (loc.x + 0, loc.y + 1, loc.z + 1, loc.w + -1),
  207.             (loc.x + 0, loc.y + 1, loc.z + 1, loc.w + 0),
  208.             (loc.x + 0, loc.y + 1, loc.z + 1, loc.w + 1),
  209.             (loc.x + 1, loc.y + -1, loc.z + -1, loc.w + -1),
  210.             (loc.x + 1, loc.y + -1, loc.z + -1, loc.w + 0),
  211.             (loc.x + 1, loc.y + -1, loc.z + -1, loc.w + 1),
  212.             (loc.x + 1, loc.y + -1, loc.z + 0, loc.w + -1),
  213.             (loc.x + 1, loc.y + -1, loc.z + 0, loc.w + 0),
  214.             (loc.x + 1, loc.y + -1, loc.z + 0, loc.w + 1),
  215.             (loc.x + 1, loc.y + -1, loc.z + 1, loc.w + -1),
  216.             (loc.x + 1, loc.y + -1, loc.z + 1, loc.w + 0),
  217.             (loc.x + 1, loc.y + -1, loc.z + 1, loc.w + 1),
  218.             (loc.x + 1, loc.y + 0, loc.z + -1, loc.w + -1),
  219.             (loc.x + 1, loc.y + 0, loc.z + -1, loc.w + 0),
  220.             (loc.x + 1, loc.y + 0, loc.z + -1, loc.w + 1),
  221.             (loc.x + 1, loc.y + 0, loc.z + 0, loc.w + -1),
  222.             (loc.x + 1, loc.y + 0, loc.z + 0, loc.w + 0),
  223.             (loc.x + 1, loc.y + 0, loc.z + 0, loc.w + 1),
  224.             (loc.x + 1, loc.y + 0, loc.z + 1, loc.w + -1),
  225.             (loc.x + 1, loc.y + 0, loc.z + 1, loc.w + 0),
  226.             (loc.x + 1, loc.y + 0, loc.z + 1, loc.w + 1),
  227.             (loc.x + 1, loc.y + 1, loc.z + -1, loc.w + -1),
  228.             (loc.x + 1, loc.y + 1, loc.z + -1, loc.w + 0),
  229.             (loc.x + 1, loc.y + 1, loc.z + -1, loc.w + 1),
  230.             (loc.x + 1, loc.y + 1, loc.z + 0, loc.w + -1),
  231.             (loc.x + 1, loc.y + 1, loc.z + 0, loc.w + 0),
  232.             (loc.x + 1, loc.y + 1, loc.z + 0, loc.w + 1),
  233.             (loc.x + 1, loc.y + 1, loc.z + 1, loc.w + -1),
  234.             (loc.x + 1, loc.y + 1, loc.z + 1, loc.w + 0),
  235.             (loc.x + 1, loc.y + 1, loc.z + 1, loc.w + 1),
  236.         };     
  237.     }
  238.  
  239. }
  240.  
  241. int SolveA(string[] data)
  242. {
  243.     var cw = new Conway3D();
  244.     return cw.Solve(data);
  245. }
  246. int SolveB(string[] data)
  247. {
  248.     var cw = new Conway4D();
  249.     return cw.Solve(data);
  250. }
  251.  
  252.  
  253. // You can define other methods, fields, classes and namespaces here
  254.  
  255. #region private::Tests
  256. //test data
  257. string[] testdata = new[]
  258. {
  259. ".#.",
  260. "..#",
  261. "###",
  262. };
  263.  
  264. //tests
  265. [Fact] void TestA() => Assert.Equal(112, SolveA(testdata));
  266. [Fact] void TestB() => Assert.Equal(848, SolveB(testdata));
  267.  
  268. #endregion
Advertisement
Add Comment
Please, Sign In to add comment