Equd

AdventOfCode 2018 Day 07

Dec 7th, 2018
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.05 KB | None | 0 0
  1. void Main()
  2. {
  3.     //test input test  
  4.     #region TestInput
  5.     var input = new string[]
  6.     {
  7.         "Step C must be finished before step A can begin.",
  8.         "Step C must be finished before step F can begin.",
  9.         "Step A must be finished before step B can begin.",
  10.         "Step A must be finished before step D can begin.",
  11.         "Step B must be finished before step E can begin.",
  12.         "Step D must be finished before step E can begin.",
  13.         "Step F must be finished before step E can begin.",
  14.     };
  15.     #endregion 
  16.    
  17.    
  18.     if(solve(input, 1, 0).sequence != "CABDFE") throw new Exception("failed test a");
  19.     if(solve(input, 2, 0) != ("CABFDE", 15)) throw new Exception("failed test b");
  20.        
  21.     //challenge
  22.     var aoc = new AdventOfCode(2018, 7);
  23.  
  24.     aoc.SubmitAnswer(solve(aoc.InputLines, 1, 0).sequence, Part.A);
  25.     aoc.SubmitAnswer(solve(aoc.InputLines, 5, 60).time, Part.B);   
  26. }  
  27.  
  28. public (string sequence, int time) solve(string[] input, int workerCount, int extraTime)
  29. {
  30.     //conver to (char, char)
  31.     var lines = input.Select(x => x.ToArray()).Select(x => (x[5], x[36])).ToList();
  32.    
  33.     //items that still need work
  34.     var stepsTodo = lines.SelectMany(x => new[] { x.Item1, x.Item2 }).Distinct().OrderBy(x => x).ToList();
  35.  
  36.     //store the result here
  37.     string result = "";
  38.  
  39.     //keeps track of the time
  40.     int time = 0;  
  41.    
  42.     //track workers
  43.     var activeWorkers = new List<(char workingOn, int timeLeft)>();
  44.        
  45.     //time stepsize
  46.     int timestep = 1;
  47.    
  48.     //we return in here somwhere
  49.     while(true)
  50.     {                      
  51.         //anything done?       
  52.         for(int i = 0; i < activeWorkers.Count; i++)
  53.         {                              
  54.             //move the worker forward in time
  55.             activeWorkers[i] = (activeWorkers[i].workingOn, activeWorkers[i].timeLeft - timestep);
  56.            
  57.             //done?
  58.             if(activeWorkers[i].timeLeft == 0)
  59.             {
  60.                 //remove from rules
  61.                 lines = lines.Where(x=> x.Item1 != activeWorkers[i].workingOn).ToList();
  62.                
  63.                 //add to result
  64.                 result += activeWorkers[i].workingOn;
  65.                
  66.                 //remove from items left todo
  67.                 stepsTodo.Remove(activeWorkers[i].workingOn);
  68.                
  69.                 //free worker, and move index 1 back because of removal
  70.                 activeWorkers.RemoveAt(i--);   
  71.                
  72.                 //are we done? then return result
  73.                 if(stepsTodo.Count == 0)
  74.                     return (result, time);
  75.             }
  76.         }
  77.        
  78.         //check each possible step if there are workers    
  79.         for (int a = 0; a < stepsTodo.Count && activeWorkers.Count < workerCount; a++)
  80.         {
  81.             //check if a step can be done
  82.             if (StepValidForWork(stepsTodo[a]))
  83.             {
  84.                 //hand step to a worker
  85.                 activeWorkers.Add((stepsTodo[a], (stepsTodo[a] - 64) + extraTime));            
  86.             }
  87.         }  
  88.        
  89.         //determine when the next timePoint of check is
  90.         timestep = activeWorkers.Min(x => x.timeLeft);
  91.        
  92.         //move forward
  93.         time += timestep;  
  94.     }
  95.  
  96.     bool StepValidForWork(char b)
  97.     {
  98.         //check if its not being worked on
  99.         for(int i = 0; i < activeWorkers.Count; i++)       
  100.             if(activeWorkers[i].workingOn == b) return false;
  101.        
  102.  
  103.         //check if a rule prohibts starting
  104.         foreach (var change in lines)      
  105.             if (change.Item2 == b && stepsTodo.Contains(b)) return false;
  106.        
  107.         //no reason not to start
  108.         return true;
  109.     }
  110. }
Advertisement
Add Comment
Please, Sign In to add comment