Advertisement
Equd

AdventOfCode 2018 Day 06

Dec 6th, 2018
229
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.26 KB | None | 0 0
  1. void Main()
  2. {
  3.     //TEST
  4.     var input = ParseInput(new string[] { "1, 1", "1, 6", "8, 3", "3, 4", "5, 5", "8, 9", });
  5.    
  6.     if(SolveA(input) != 17) throw new Exception();
  7.     if (SolveB(input.Keys.ToArray(), 32) != 16) throw new Exception();
  8.    
  9.     //actual
  10.     var aoc = new AdventOfCode(2018, 6);
  11.     input = ParseInput(aoc.InputLines);
  12.    
  13.     aoc.SubmitAnswer(SolveA(input), Part.A);
  14.     aoc.SubmitAnswer(SolveB(input.Keys.ToArray(), 10_000), Part.B);
  15.  
  16.  
  17. }
  18.  
  19. public int SolveA(Dictionary<Point, char> dic)
  20. {
  21.     //grid dimensions
  22.     var maxX = dic.Keys.Select(x => x.X).Max() + 2;
  23.     var maxY = dic.Keys.Select(x => x.Y).Max() + 2;
  24.  
  25.     //track if it touches the side
  26.     var touchesSide = new HashSet<char>();
  27.  
  28.     //next round dictionary
  29.     Dictionary<Point, char> nextDic = new Dictionary<Point, char>();
  30.  
  31.     //create grid
  32.     var grid = new char[maxX, maxY];
  33.    
  34.     //all places vistited?
  35.     while (dic.Count != 0)
  36.     {
  37.         //add each item
  38.         foreach (var kv in dic)
  39.         {                      
  40.             var loc = kv.Key;
  41.            
  42.             //touches side?
  43.             if(loc.X == 0 || loc.Y == 0 || loc.X + 1 == maxX || loc.Y + 1 == maxY) touchesSide.Add(kv.Value);                      
  44.                        
  45.             //already claimed?
  46.             if(grid[loc.X, loc.Y] != '\0') continue;
  47.            
  48.             //set value
  49.             grid[loc.X, loc.Y] = kv.Value;
  50.            
  51.             //add all directions to claim
  52.             //up
  53.             if (loc.X - 1 >= 0 && grid[loc.X - 1, loc.Y + 0] == '\0') Add(new Point(loc.X - 1, loc.Y + 0), kv.Value);
  54.             //down                                                     
  55.             if (loc.X + 1 < maxX && grid[loc.X + 1, loc.Y + 0] == '\0') Add(new Point(loc.X + 1, loc.Y + 0), kv.Value);
  56.             //left                                                     
  57.             if (loc.Y - 1 >= 0 && grid[loc.X - 0, loc.Y - 1] == '\0') Add(new Point(loc.X - 0, loc.Y - 1), kv.Value);
  58.             //right                                                    
  59.             if (loc.Y + 1 < maxY && grid[loc.X - 0, loc.Y + 1] == '\0') Add(new Point(loc.X + 0, loc.Y + 1), kv.Value);
  60.         }
  61.  
  62.         //create new dic for next round
  63.         dic = nextDic;
  64.         nextDic = new Dictionary<Point, char>();       
  65.     }
  66.    
  67.    
  68.    
  69.     return grid.Cast<char>() //flatten
  70.         .Where(x => touchesSide.Contains(x) == false).GroupBy(x=> x) //remove those that touch side
  71.         .Select(x => new {x.Key, count = x.Count()}) //parse readable
  72.         .OrderByDescending(x => x.count) //sort
  73.         .First().count; //keep biggest
  74.  
  75.     //method to add items to the dictionary
  76.     void Add(Point p, char i)
  77.     {
  78.         if (nextDic.TryGetValue(p, out char e))
  79.         {
  80.             //if claimed by differnt, make .
  81.             if (e != i) nextDic[p] = '.';
  82.         }
  83.         //add item for next round
  84.         else
  85.             nextDic.Add(p, i);
  86.     }
  87.  
  88. }
  89.  
  90. //parse the input
  91. public Dictionary<Point, char> ParseInput(string[] input)
  92. {
  93.     return input
  94.         .Select(x => x.Split(','))
  95.         .Select((x, index) => (x, index))
  96.         .ToDictionary(x => new Point(int.Parse(x.x[1]), int.Parse(x.x[0])), x => (char)(x.index + 65));
  97. }
  98.  
  99.  
  100. public int SolveB(Point[] lst, int max)
  101. {
  102.     //grid dimension
  103.     var maxX = lst.Select(x => x.X).Max();
  104.     var maxY = lst.Select(x => x.Y).Max();
  105.    
  106.     //size of biggest (if not a single patch this breaks!)
  107.     int size = 0;
  108.  
  109.     //check each position
  110.     for (int x = 0; x < maxX; x++)
  111.     {      
  112.         for (int y = 0; y < maxY; y++)
  113.         {
  114.             //calc distance
  115.             int sum = 0;
  116.             foreach (var i in lst)
  117.             {
  118.                 sum += Math.Abs(i.X - x) + Math.Abs(i.Y - y);
  119.                 if (sum > max) break; //bigger? lets goto the next
  120.             }
  121.             if (sum < max) size++; //increase patch size counter
  122.         }
  123.     }
  124.  
  125.     return size;
  126. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement