feat: solve day 5 part 1
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
namespace PrintQueue.Tests;
|
||||
|
||||
public class PuzzleParserTests
|
||||
{
|
||||
private readonly PuzzleParser _puzzleParser = new();
|
||||
private readonly string _exampleInput = $"47|53{Environment.NewLine}97|13{Environment.NewLine}97|61{Environment.NewLine}97|47{Environment.NewLine}75|29{Environment.NewLine}61|13{Environment.NewLine}75|53{Environment.NewLine}29|13{Environment.NewLine}97|29{Environment.NewLine}53|29{Environment.NewLine}61|53{Environment.NewLine}97|53{Environment.NewLine}61|29{Environment.NewLine}47|13{Environment.NewLine}75|47{Environment.NewLine}97|75{Environment.NewLine}47|61{Environment.NewLine}75|61{Environment.NewLine}47|29{Environment.NewLine}75|13{Environment.NewLine}53|13{Environment.NewLine}{Environment.NewLine}75,47,61,53,29{Environment.NewLine}97,61,53,29,13{Environment.NewLine}75,29,13{Environment.NewLine}75,97,47,61,53{Environment.NewLine}61,13,29{Environment.NewLine}97,13,75,29,47";
|
||||
|
||||
private static async Task<string> GetPuzzleInput()
|
||||
{
|
||||
return await File.ReadAllTextAsync(Path.Combine(AppContext.BaseDirectory, "INPUT.txt"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Parse_WhenGivenExampleInput_ItShouldReturnExpectedRules()
|
||||
{
|
||||
var result = _puzzleParser.Parse(_exampleInput);
|
||||
|
||||
await Assert.That(result.Rules).IsEquivalentTo(new List<OrderRule>()
|
||||
{
|
||||
new(47, 53),
|
||||
new(97, 13),
|
||||
new(97, 61),
|
||||
new(97, 47),
|
||||
new(75, 29),
|
||||
new(61, 13),
|
||||
new(75, 53),
|
||||
new(29, 13),
|
||||
new(97, 29),
|
||||
new(53, 29),
|
||||
new(61, 53),
|
||||
new(97, 53),
|
||||
new(61, 29),
|
||||
new(47, 13),
|
||||
new(75, 47),
|
||||
new(97, 75),
|
||||
new(47, 61),
|
||||
new(75, 61),
|
||||
new(47, 29),
|
||||
new(75, 13),
|
||||
new(53, 13),
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Parse_WhenGivenExampleInput_ItShouldReturnExpectedUpdates()
|
||||
{
|
||||
var result = _puzzleParser.Parse(_exampleInput);
|
||||
|
||||
await Assert.That(result.Updates).IsEquivalentTo(new List<Update>()
|
||||
{
|
||||
new([75,47,61,53,29]),
|
||||
new([97,61,53,29,13]),
|
||||
new([75,29,13]),
|
||||
new([75,97,47,61,53]),
|
||||
new([61,13,29]),
|
||||
new([97,13,75,29,47]),
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Parse_WhenGivenPuzzleInput_ItShouldReturnExpectedResult()
|
||||
{
|
||||
var input = await GetPuzzleInput();
|
||||
|
||||
var parseResult = _puzzleParser.Parse(input);
|
||||
|
||||
var validator = new UpdateValidator(parseResult.Rules);
|
||||
|
||||
var result = parseResult.Updates
|
||||
.Where(u => validator.Validate(u))
|
||||
.Select(u => u.GetMiddlePage())
|
||||
.Sum();
|
||||
|
||||
await Assert.That(result).IsEqualTo(6260);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
namespace PrintQueue.Tests;
|
||||
|
||||
public class UpdateTests
|
||||
{
|
||||
[Test]
|
||||
public async Task GetMiddlePage_WhenCalled_ItShouldReturnExpectedPage()
|
||||
{
|
||||
var updates = new List<Update>()
|
||||
{
|
||||
new([75,47,61,53,29]),
|
||||
new([97,61,53,29,13]),
|
||||
new([75,29,13]),
|
||||
};
|
||||
|
||||
var result = updates.Select(u => u.GetMiddlePage()).Sum();
|
||||
|
||||
await Assert.That(result).IsEqualTo(143);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
namespace PrintQueue.Tests;
|
||||
|
||||
public class UpdateValidatorTests
|
||||
{
|
||||
private readonly List<OrderRule> _exampleRules = [
|
||||
new(47, 53),
|
||||
new(97, 13),
|
||||
new(97, 61),
|
||||
new(97, 47),
|
||||
new(75, 29),
|
||||
new(61, 13),
|
||||
new(75, 53),
|
||||
new(29, 13),
|
||||
new(97, 29),
|
||||
new(53, 29),
|
||||
new(61, 53),
|
||||
new(97, 53),
|
||||
new(61, 29),
|
||||
new(47, 13),
|
||||
new(75, 47),
|
||||
new(97, 75),
|
||||
new(47, 61),
|
||||
new(75, 61),
|
||||
new(47, 29),
|
||||
new(75, 13),
|
||||
new(53, 13),
|
||||
];
|
||||
|
||||
[Test]
|
||||
public async Task Graph_WhenGivenExampleRules_ItShouldBuildExpectedGraph()
|
||||
{
|
||||
var expectedGraph = new Dictionary<int, HashSet<int>>()
|
||||
{
|
||||
{ 47, [53, 13, 61, 29] },
|
||||
{ 53, [29, 13] },
|
||||
{ 97, [13, 61, 47, 29, 53, 75] },
|
||||
{ 13, [] },
|
||||
{ 61, [13, 53, 29] },
|
||||
{ 75, [29, 53, 47, 61, 13] },
|
||||
{ 29, [13] },
|
||||
};
|
||||
|
||||
var validator = new UpdateValidator(_exampleRules);
|
||||
|
||||
await Assert.That(validator.Graph.Keys).IsEquivalentTo(expectedGraph.Keys);
|
||||
await Assert.That(validator.Graph.Values).IsEquivalentTo(expectedGraph.Values);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Validate_WhenGivenValidUpdate_ItShouldReturnTrue()
|
||||
{
|
||||
var updateOne = new Update([75, 47, 61, 53, 29]);
|
||||
var updateTwo = new Update([97,61,53,29,13]);
|
||||
var updateThree = new Update([75,29,13]);
|
||||
|
||||
var validator = new UpdateValidator(_exampleRules);
|
||||
|
||||
var resultOne = validator.Validate(updateOne);
|
||||
var resultTwo = validator.Validate(updateTwo);
|
||||
var resultThree = validator.Validate(updateThree);
|
||||
|
||||
await Assert.That(resultOne).IsTrue();
|
||||
await Assert.That(resultTwo).IsTrue();
|
||||
await Assert.That(resultThree).IsTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Validate_WhenGivenInvalidUpdate_ItShouldReturnFalse()
|
||||
{
|
||||
var updateOne = new Update([75,97,47,61,53]);
|
||||
var updateTwo = new Update([61,13,29]);
|
||||
var updateThree = new Update([97,13,75,29,47]);
|
||||
|
||||
var validator = new UpdateValidator(_exampleRules);
|
||||
|
||||
var resultOne = validator.Validate(updateOne);
|
||||
var resultTwo = validator.Validate(updateTwo);
|
||||
var resultThree = validator.Validate(updateThree);
|
||||
|
||||
await Assert.That(resultOne).IsFalse();
|
||||
await Assert.That(resultTwo).IsFalse();
|
||||
await Assert.That(resultThree).IsFalse();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
namespace PrintQueue;
|
||||
|
||||
record OrderRule(int X, int Y);
|
||||
@@ -0,0 +1,3 @@
|
||||
namespace PrintQueue;
|
||||
|
||||
record ParseResult(List<OrderRule> Rules, List<Update> Updates);
|
||||
@@ -1,5 +1,7 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
using PrintQueue;
|
||||
|
||||
if (args.Length is 0)
|
||||
{
|
||||
Console.WriteLine("Please provide a path to the input file.");
|
||||
@@ -13,14 +15,21 @@ if (File.Exists(args[0]) is false)
|
||||
}
|
||||
|
||||
var isPart2 = args.Length is 2 && args[1] is "part2";
|
||||
var input = await File.ReadAllLinesAsync(args[0]);
|
||||
var input = await File.ReadAllTextAsync(args[0]);
|
||||
|
||||
var stopwatch = new Stopwatch();
|
||||
stopwatch.Start();
|
||||
|
||||
// TODO: Perform work here
|
||||
var parser = new PuzzleParser();
|
||||
|
||||
var parseResult = parser.Parse(input);
|
||||
|
||||
var validator = new UpdateValidator(parseResult.Rules);
|
||||
|
||||
var result = parseResult.Updates
|
||||
.Where(u => validator.Validate(u))
|
||||
.Select(u => u.GetMiddlePage())
|
||||
.Sum();
|
||||
|
||||
stopwatch.Stop();
|
||||
|
||||
// TODO: Print results
|
||||
Console.WriteLine($". ({stopwatch.ElapsedMilliseconds}ms)");
|
||||
Console.WriteLine($"The sum of the page numbers is {result}. ({stopwatch.ElapsedMilliseconds}ms)");
|
||||
@@ -0,0 +1,36 @@
|
||||
namespace PrintQueue;
|
||||
|
||||
class PuzzleParser
|
||||
{
|
||||
public ParseResult Parse(string input)
|
||||
{
|
||||
var inputParts = input.Split($"{Environment.NewLine}{Environment.NewLine}");
|
||||
var rules = ParseRules(inputParts[0]);
|
||||
var updates = ParseUpdates(inputParts[1]);
|
||||
return new ParseResult(rules, updates);
|
||||
}
|
||||
|
||||
private static List<Update> ParseUpdates(string input)
|
||||
{
|
||||
return input.Split(Environment.NewLine)
|
||||
.Select(s => new Update(
|
||||
s.Split(",").Select(int.Parse).ToList()
|
||||
))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private static List<OrderRule> ParseRules(string input)
|
||||
{
|
||||
return input
|
||||
.Split(Environment.NewLine)
|
||||
.Select(s =>
|
||||
{
|
||||
var parts = s.Split("|");
|
||||
return new OrderRule(
|
||||
int.Parse(parts[0]),
|
||||
int.Parse(parts[1])
|
||||
);
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace PrintQueue;
|
||||
|
||||
record Update(List<int> Pages)
|
||||
{
|
||||
public int GetMiddlePage()
|
||||
{
|
||||
return Pages.Count is 0 ? 0 : Pages[Pages.Count / 2];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
namespace PrintQueue;
|
||||
|
||||
class UpdateValidator
|
||||
{
|
||||
public readonly Dictionary<int, HashSet<int>> Graph = [];
|
||||
|
||||
public UpdateValidator(List<OrderRule> rules)
|
||||
{
|
||||
foreach (var rule in rules)
|
||||
{
|
||||
if (Graph.ContainsKey(rule.X) is false)
|
||||
{
|
||||
Graph.Add(rule.X, []);
|
||||
}
|
||||
|
||||
if (Graph.ContainsKey(rule.Y) is false)
|
||||
{
|
||||
Graph.Add(rule.Y, []);
|
||||
}
|
||||
|
||||
Graph[rule.X].Add(rule.Y);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Validate(Update update)
|
||||
{
|
||||
var previousPages = new List<int>();
|
||||
|
||||
foreach (var page in update.Pages)
|
||||
{
|
||||
foreach (var previousPage in previousPages)
|
||||
{
|
||||
if (
|
||||
Graph.TryGetValue(previousPage, out HashSet<int>? value) &&
|
||||
value.Contains(page) is false
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
previousPages.Add(page);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user