add a few more solutions
This commit is contained in:
14
Level5/Level5.csproj
Normal file
14
Level5/Level5.csproj
Normal file
@@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../Common/Common.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
252
Level5/Level5Solver.cs
Normal file
252
Level5/Level5Solver.cs
Normal file
@@ -0,0 +1,252 @@
|
||||
namespace AoC24;
|
||||
|
||||
using AoC24.Common;
|
||||
using AoCLevelInputProvider;
|
||||
using Parsing;
|
||||
using Parsing.Schema;
|
||||
|
||||
public class Rule
|
||||
{
|
||||
public string NumLeft { get; set; }
|
||||
public string NumRight { get; set; }
|
||||
|
||||
public Rule(string numLeft, string numRight)
|
||||
{
|
||||
NumLeft = numLeft;
|
||||
NumRight = numRight;
|
||||
}
|
||||
|
||||
public bool IsApplicable(List<string> inputs)
|
||||
{
|
||||
return inputs.Contains(NumLeft) && inputs.Contains(NumRight);
|
||||
}
|
||||
|
||||
public bool IsValid(List<string> inputs)
|
||||
{
|
||||
if(!IsApplicable(inputs))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
for(int i = 0; i < inputs.Count; i++)
|
||||
{
|
||||
if(inputs[i].Equals(NumRight))
|
||||
{
|
||||
//Console.WriteLine("Matched NumRight:" + inputs[i]);
|
||||
return false;
|
||||
}
|
||||
if(inputs[i].Equals(NumLeft))
|
||||
{
|
||||
//Console.WriteLine("Matched NumLeft:" + inputs[i]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public class RuleSet
|
||||
{
|
||||
public List<Rule> Rules { get; set; } = new List<Rule>();
|
||||
|
||||
public RuleSet()
|
||||
{}
|
||||
|
||||
public bool IsValid(List<string> inputs)
|
||||
{
|
||||
foreach(var rule in Rules)
|
||||
{
|
||||
if(!rule.IsValid(inputs))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public class RuleOrderer
|
||||
{
|
||||
private List<Rule> rules;
|
||||
|
||||
public RuleOrderer(List<Rule> rules)
|
||||
{
|
||||
this.rules = rules;
|
||||
}
|
||||
|
||||
public bool RuleExistsThatPutsThisPageFirst(string page, string pageToCompareTo)
|
||||
{
|
||||
foreach (var rule in rules)
|
||||
{
|
||||
if(rule.NumLeft == page && rule.NumRight == pageToCompareTo)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<string> OrderViaRules(List<string> input)
|
||||
{
|
||||
var sortedList = new List<string>();
|
||||
|
||||
foreach(string num in input)
|
||||
{
|
||||
if(sortedList.Count == 0)
|
||||
{
|
||||
sortedList.Add(num);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i = 0; i < sortedList.Count; i++)
|
||||
{
|
||||
var compareNum = sortedList[i];
|
||||
if(this.RuleExistsThatPutsThisPageFirst(num, compareNum))
|
||||
{
|
||||
sortedList.Insert(i, num);
|
||||
//Console.WriteLine(string.Join(",", sortedList));
|
||||
break;
|
||||
}
|
||||
if( i == sortedList.Count - 1)
|
||||
{
|
||||
sortedList.Add(num);
|
||||
//Console.WriteLine(string.Join(",", sortedList));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Console.WriteLine("=================");
|
||||
// Console.WriteLine("Input: " + string.Join(",", input));
|
||||
// Console.WriteLine("Applicable rules: ");
|
||||
// foreach(var rule in rules.ToList().OrderBy(x => x.NumLeft))
|
||||
// {
|
||||
// Console.WriteLine(rule.NumLeft + "|" + rule.NumRight);
|
||||
// }
|
||||
// Console.WriteLine("Output: " + string.Join(",", sortedList));
|
||||
// Console.ReadLine();
|
||||
|
||||
return sortedList;
|
||||
}
|
||||
}
|
||||
|
||||
public class Level5Solver: FragmentLevelSolverBase
|
||||
{
|
||||
public override int LevelNumber
|
||||
{
|
||||
get { return 5; }
|
||||
}
|
||||
|
||||
protected override FragmentSchemaBuilder DefineInputSchema(FragmentSchemaBuilder schemaBuilder)
|
||||
{
|
||||
return schemaBuilder
|
||||
.StartOptions()
|
||||
.Option()
|
||||
.Expect(InputType.Integer, "rule_left")
|
||||
.Expect("|")
|
||||
.Expect(InputType.Integer, "rule_right")
|
||||
.Option()
|
||||
.Expect(InputType.Integer, "pages")
|
||||
.Repeat()
|
||||
.Expect(",")
|
||||
.Expect(InputType.Integer, "pages")
|
||||
.EndRepetition()
|
||||
.EndOptions();
|
||||
}
|
||||
|
||||
public override string SolveFirstStar()
|
||||
{
|
||||
var data = this.GetData()
|
||||
.AsFragments();
|
||||
|
||||
var validSequences = new List<List<string>>();
|
||||
var ruleset = new RuleSet();
|
||||
|
||||
foreach(var fragment in data)
|
||||
{
|
||||
if(fragment["rule_left"].Count > 0)
|
||||
{
|
||||
//Console.WriteLine("Adding rule: " + fragment["rule_left"][0] + "|" + fragment["rule_right"][0]);
|
||||
ruleset.Rules.Add(new Rule(fragment["rule_left"][0], fragment["rule_right"][0]));
|
||||
}
|
||||
else
|
||||
{
|
||||
//Console.WriteLine(string.Join(",", fragment["pages"]));
|
||||
if(ruleset.IsValid(fragment["pages"]))
|
||||
{
|
||||
//Console.WriteLine("Adding fragment: " + string.Join(",", fragment["pages"]));
|
||||
validSequences.Add(fragment["pages"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var count = 0;
|
||||
|
||||
foreach(var sequence in validSequences)
|
||||
{
|
||||
var middleItem = sequence[sequence.Count/2];
|
||||
count += int.Parse(middleItem);
|
||||
}
|
||||
|
||||
return count.ToString();
|
||||
}
|
||||
|
||||
public override string SolveSecondStar()
|
||||
{
|
||||
var data = this.GetData()
|
||||
.AsFragments();
|
||||
|
||||
var invalidSequences = new List<List<string>>();
|
||||
var ruleset = new RuleSet();
|
||||
|
||||
foreach(var fragment in data)
|
||||
{
|
||||
if(fragment["rule_left"].Count > 0)
|
||||
{
|
||||
//Console.WriteLine("Adding rule: " + fragment["rule_left"][0] + "|" + fragment["rule_right"][0]);
|
||||
ruleset.Rules.Add(new Rule(fragment["rule_left"][0], fragment["rule_right"][0]));
|
||||
}
|
||||
else
|
||||
{
|
||||
//Console.WriteLine(string.Join(",", fragment["pages"]));
|
||||
if(!ruleset.IsValid(fragment["pages"]))
|
||||
{
|
||||
//Console.WriteLine("Adding fragment: " + string.Join(",", fragment["pages"]));
|
||||
invalidSequences.Add(fragment["pages"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var orderedSequences = new List<List<string>>();
|
||||
|
||||
foreach(var sequence in invalidSequences)
|
||||
{
|
||||
var applicableRules = new List<Rule>();
|
||||
foreach(var rule in ruleset.Rules)
|
||||
{
|
||||
if(rule.IsApplicable(sequence))
|
||||
{
|
||||
applicableRules.Add(rule);
|
||||
}
|
||||
}
|
||||
|
||||
var orderer = new RuleOrderer(applicableRules);
|
||||
var orderedSequence = orderer.OrderViaRules(sequence);
|
||||
if(!ruleset.IsValid(orderedSequence))
|
||||
{
|
||||
throw new Exception("badbadbad");
|
||||
}
|
||||
orderedSequences.Add(orderedSequence);
|
||||
}
|
||||
|
||||
var count = 0;
|
||||
|
||||
foreach(var sequence in orderedSequences)
|
||||
{
|
||||
var middleItem = sequence[sequence.Count/2];
|
||||
count += int.Parse(middleItem);
|
||||
}
|
||||
|
||||
return count.ToString();
|
||||
}
|
||||
}
|
||||
24
Level5/Program.cs
Normal file
24
Level5/Program.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
// See https://aka.ms/new-console-template for more information
|
||||
|
||||
using AoC24;
|
||||
|
||||
var levelSolver = new Level5Solver();
|
||||
var solution1 = levelSolver.SolveFirstStar();
|
||||
var solution2 = levelSolver.SolveSecondStar();
|
||||
|
||||
if (!string.IsNullOrEmpty(solution1))
|
||||
{
|
||||
Console.WriteLine("Solution for example 1 is: " + solution1);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Example 1 has not been solved yet!");
|
||||
}
|
||||
if (!string.IsNullOrEmpty(solution2))
|
||||
{
|
||||
Console.WriteLine("Solution for example 2 is: " + solution2);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Example 2 has not been solved yet!");
|
||||
}
|
||||
Reference in New Issue
Block a user