Files
AOC_2024/dotnet/05/05a.cs
2024-12-10 14:36:10 -06:00

168 lines
4.4 KiB
C#

void Main1()
{
var lines = File.ReadAllLines(Path.Join("..", "..", "05a.txt")).Select(l => l.Trim()).ToList();
if (lines.Last() == "")
lines.RemoveAt(lines.Count - 1);
List<Rule> rules = new();
foreach (var line in lines.TakeWhile(l => !string.IsNullOrWhiteSpace(l)))
{
var parts = line.Split('|');
rules.Add(new(
int.Parse(parts[0]),
int.Parse(parts[1])
));
}
List<Collection> collections = new();
foreach (var line in lines.SkipWhile(l => !string.IsNullOrWhiteSpace(l)).Skip(1))
{
var parts = line.Split(',').Select(int.Parse);
collections.Add(new(parts));
}
int total = 0;
foreach (var collection in collections.Where(c => rules.All(r => c.TestRule(r))))
{
total += collection.Middle();
}
Console.WriteLine(total);
}
void Main2()
{
var lines = File.ReadAllLines(Path.Join("..", "..", "05a.txt")).Select(l => l.Trim()).ToList();
if (lines.Last() == "")
lines.RemoveAt(lines.Count - 1);
List<Rule> rules = new();
RuleList rulelist = new();
foreach (var line in lines.TakeWhile(l => !string.IsNullOrWhiteSpace(l)))
{
var parts = line.Split('|');
Rule rule = new(
int.Parse(parts[0]),
int.Parse(parts[1])
);
rulelist.Add(rule);
rules.Add(rule);
}
List<Collection> collections = new();
foreach (var line in lines.SkipWhile(l => !string.IsNullOrWhiteSpace(l)).Skip(1))
{
var parts = line.Split(',').Select(int.Parse);
collections.Add(new(parts));
}
var total = 0;
var count = 0;
foreach (var collection in collections)
{
var r = collection.Pairs()
.Select(p => rulelist.ExtractRule(p.Item1, p.Item2))
.Where(r => r is not null)
.Select(r => (Rule)r)
.ToList();
if (!rules.All(collection.TestRule))
{
collection.Pages.Sort(rulelist.Compare);
total += collection.Pages[collection.Pages.Count / 2];
count++;
}
}
Console.WriteLine($"Collections: {collections.Count}");
Console.WriteLine($"With errors: {count}");
Console.WriteLine($"Solution: {total}");
}
Main2();
record struct Rule(int First, int Second);
class RuleList
{
Dictionary<(int,int), bool> Rules = new();
public RuleList()
{
}
public void Add(Rule rule)
{
bool ordered = rule.First < rule.Second;
var pair = ordered
? (rule.First, rule.Second)
: (rule.Second, rule.First);
Rules.Add(pair, ordered);
}
//true if correct order, null if no rule
public bool? Check(int a, int b)
{
bool ordered = a < b;
var pair = ordered
? (a, b)
: (b, a);
bool result;
return Rules.TryGetValue(pair, out result) ? result ^ ordered : null;
}
public int Compare(int a, int b)
{
var check = Check(a, b);
if (check is bool _check)
return _check ? -1 : 1;
return 0;
}
public Rule? ExtractRule(int a, int b)
{
var check = Check(a, b);
if (check is bool _check)
return _check ? new(a, b) : new(b, a);
return null;
}
}
class Collection
{
public readonly List<int> Pages;
public Collection(IEnumerable<int> pages)
{
Pages = pages.ToList();
}
public bool TestRule(Rule rule)
{
bool foundFirst = false;
bool foundSecond = false;
foreach (var page in Pages)
{
if (page == rule.First)
{
if (foundSecond)
return false;
foundFirst = true;
}
if (page == rule.Second)
{
if (foundFirst)
return true;
foundSecond = true;
}
}
return true;
}
public int Middle()
{
return Pages[Pages.Count / 2];
}
public List<(int,int)> Pairs()
{
List<(int,int)> pairs = new();
for (int i = 0; i < Pages.Count-1; i++)
{
for (int j = i+1; j < Pages.Count; j++)
{
pairs.Add((Pages[i], Pages[j]));
}
}
return pairs;
}
}