Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- void Main()
- {
- //TEST
- var input = ParseInput(new string[] { "1, 1", "1, 6", "8, 3", "3, 4", "5, 5", "8, 9", });
- if(SolveA(input) != 17) throw new Exception();
- if (SolveB(input.Keys.ToArray(), 32) != 16) throw new Exception();
- //actual
- var aoc = new AdventOfCode(2018, 6);
- input = ParseInput(aoc.InputLines);
- aoc.SubmitAnswer(SolveA(input), Part.A);
- aoc.SubmitAnswer(SolveB(input.Keys.ToArray(), 10_000), Part.B);
- }
- public int SolveA(Dictionary<Point, char> dic)
- {
- //grid dimensions
- var maxX = dic.Keys.Select(x => x.X).Max() + 2;
- var maxY = dic.Keys.Select(x => x.Y).Max() + 2;
- //track if it touches the side
- var touchesSide = new HashSet<char>();
- //next round dictionary
- Dictionary<Point, char> nextDic = new Dictionary<Point, char>();
- //create grid
- var grid = new char[maxX, maxY];
- //all places vistited?
- while (dic.Count != 0)
- {
- //add each item
- foreach (var kv in dic)
- {
- var loc = kv.Key;
- //touches side?
- if(loc.X == 0 || loc.Y == 0 || loc.X + 1 == maxX || loc.Y + 1 == maxY) touchesSide.Add(kv.Value);
- //already claimed?
- if(grid[loc.X, loc.Y] != '\0') continue;
- //set value
- grid[loc.X, loc.Y] = kv.Value;
- //add all directions to claim
- //up
- if (loc.X - 1 >= 0 && grid[loc.X - 1, loc.Y + 0] == '\0') Add(new Point(loc.X - 1, loc.Y + 0), kv.Value);
- //down
- if (loc.X + 1 < maxX && grid[loc.X + 1, loc.Y + 0] == '\0') Add(new Point(loc.X + 1, loc.Y + 0), kv.Value);
- //left
- if (loc.Y - 1 >= 0 && grid[loc.X - 0, loc.Y - 1] == '\0') Add(new Point(loc.X - 0, loc.Y - 1), kv.Value);
- //right
- if (loc.Y + 1 < maxY && grid[loc.X - 0, loc.Y + 1] == '\0') Add(new Point(loc.X + 0, loc.Y + 1), kv.Value);
- }
- //create new dic for next round
- dic = nextDic;
- nextDic = new Dictionary<Point, char>();
- }
- return grid.Cast<char>() //flatten
- .Where(x => touchesSide.Contains(x) == false).GroupBy(x=> x) //remove those that touch side
- .Select(x => new {x.Key, count = x.Count()}) //parse readable
- .OrderByDescending(x => x.count) //sort
- .First().count; //keep biggest
- //method to add items to the dictionary
- void Add(Point p, char i)
- {
- if (nextDic.TryGetValue(p, out char e))
- {
- //if claimed by differnt, make .
- if (e != i) nextDic[p] = '.';
- }
- //add item for next round
- else
- nextDic.Add(p, i);
- }
- }
- //parse the input
- public Dictionary<Point, char> ParseInput(string[] input)
- {
- return input
- .Select(x => x.Split(','))
- .Select((x, index) => (x, index))
- .ToDictionary(x => new Point(int.Parse(x.x[1]), int.Parse(x.x[0])), x => (char)(x.index + 65));
- }
- public int SolveB(Point[] lst, int max)
- {
- //grid dimension
- var maxX = lst.Select(x => x.X).Max();
- var maxY = lst.Select(x => x.Y).Max();
- //size of biggest (if not a single patch this breaks!)
- int size = 0;
- //check each position
- for (int x = 0; x < maxX; x++)
- {
- for (int y = 0; y < maxY; y++)
- {
- //calc distance
- int sum = 0;
- foreach (var i in lst)
- {
- sum += Math.Abs(i.X - x) + Math.Abs(i.Y - y);
- if (sum > max) break; //bigger? lets goto the next
- }
- if (sum < max) size++; //increase patch size counter
- }
- }
- return size;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement