Skip to content

Commit

Permalink
Day 7 part 2
Browse files Browse the repository at this point in the history
  • Loading branch information
jongeorge1 committed Feb 18, 2019
1 parent 60ba5e9 commit cbba630
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 0 deletions.
68 changes: 68 additions & 0 deletions AoC2018.Solutions/Day07/Part02.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
namespace AoC2018.Solutions.Day07
{
using System;
using System.Collections.Generic;
using System.Linq;

public class Part02 : ISolution
{
public string Solve(string input) => this.Solve(input, 5, 60);

public string Solve(string input, int workers, int baseStepTime)
{
(char Step, char PreRequisite)[] statements = input.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).Select(this.ParseStatement).ToArray();
char[] allSteps = statements.Select(x => x.Step).Union(statements.Select(x => x.PreRequisite)).Distinct().ToArray();
var stepsWithDependencies = allSteps.ToDictionary(x => x, x => statements.Where(s => s.Step == x).Select(s => s.PreRequisite).ToArray());

var resolvedSteps = new List<char>();
var inProgressSteps = new List<(char Step, int CompletionTime)>();
int second = 0;

do
{
// Complete any in progress steps that are done
foreach ((char Step, int CompletionTime) current in inProgressSteps)
{
if (current.CompletionTime < second)
{
resolvedSteps.Add(current.Step);
}
}

inProgressSteps = inProgressSteps.Where(x => !resolvedSteps.Contains(x.Step)).ToList();

// If we have any space, take the next available step
while (inProgressSteps.Count < workers)
{
char nextStep = this.GetNextAvailableStep(stepsWithDependencies, resolvedSteps, inProgressSteps);

if (nextStep == default(char))
{
// No available steps
break;
}

int nextStepFinishedBy = second + baseStepTime + nextStep - 'A';
inProgressSteps.Add((nextStep, nextStepFinishedBy));
}

second++;

} while (resolvedSteps.Count != allSteps.Length);

// We will have counted on to the next second after completion...
return (second - 1).ToString();
}

private char GetNextAvailableStep(Dictionary<char, char[]> stepsWithDependencies, List<char> resolvedSteps, List<(char Step, int CompletionTime)> inProgressSteps)
{
return stepsWithDependencies.Where(x => !resolvedSteps.Contains(x.Key) && !inProgressSteps.Any(p => p.Step == x.Key) && x.Value.All(y => resolvedSteps.Contains(y))).Select(x => x.Key).OrderBy(x => x).FirstOrDefault();
}

private (char Step, char PreRequisite) ParseStatement(string statement)
{
string[] components = statement.Split(' ');
return (components[7][0], components[1][0]);
}
}
}
8 changes: 8 additions & 0 deletions AoC2018.Tests/AoCTestCases.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,13 @@ public void Day06Part02()
string result = solution.Solve("1, 1\r\n1, 6\r\n8, 3\r\n3, 4\r\n5, 5\r\n8, 9", 32);
Assert.That(result, Is.EqualTo("16"));
}

[Test]
public void Day07Part02()
{
var solution = new AoC2018.Solutions.Day07.Part02();
string result = solution.Solve("Step C must be finished before step A can begin.\r\nStep C must be finished before step F can begin.\r\nStep A must be finished before step B can begin.\r\nStep A must be finished before step D can begin.\r\nStep B must be finished before step E can begin.\r\nStep D must be finished before step E can begin.\r\nStep F must be finished before step E can begin.", 2, 0);
Assert.That(result, Is.EqualTo("15"));
}
}
}

0 comments on commit cbba630

Please sign in to comment.