168 lines
4.4 KiB
C#
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;
|
|
}
|
|
}
|