Day 5
This commit is contained in:
96
AdventOfCode/Problems/AOC2024/Day5/PageList.cs
Normal file
96
AdventOfCode/Problems/AOC2024/Day5/PageList.cs
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Rule = (int after, int before);
|
||||||
|
|
||||||
|
|
||||||
|
namespace AdventOfCode.Problems.AOC2024.Day5;
|
||||||
|
internal class PageList
|
||||||
|
{
|
||||||
|
private readonly List<Rule> _rules;
|
||||||
|
private PageNode _root;
|
||||||
|
|
||||||
|
public PageList(int[] pages, List<Rule> rules)
|
||||||
|
{
|
||||||
|
_rules = rules.Where(r => pages.Contains(r.before)).ToList();
|
||||||
|
_root = new PageNode(pages[0], GetRulesForPage(pages[0]));
|
||||||
|
for (int i = 1; i < pages.Length; i++)
|
||||||
|
AddPage(pages[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddPage(int page)
|
||||||
|
{
|
||||||
|
var node = new PageNode(page, GetRulesForPage(page));
|
||||||
|
if(node.IsBefore(_root))
|
||||||
|
{
|
||||||
|
node.NextNode = _root;
|
||||||
|
_root = node;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var curNode = _root;
|
||||||
|
while(curNode != null)
|
||||||
|
{
|
||||||
|
if(curNode.IsBefore(node))
|
||||||
|
{
|
||||||
|
if(curNode.NextNode == null)
|
||||||
|
{
|
||||||
|
curNode.NextNode = node;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(node.IsBefore(curNode.NextNode))
|
||||||
|
{
|
||||||
|
node.NextNode = curNode.NextNode;
|
||||||
|
curNode.NextNode = node;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
curNode = curNode.NextNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Rule> GetRulesForPage(int page)
|
||||||
|
{
|
||||||
|
return _rules.Where(r => r.after == page).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<int> Traverse()
|
||||||
|
{
|
||||||
|
var list = new List<int>();
|
||||||
|
var curNode = _root;
|
||||||
|
while(curNode != null)
|
||||||
|
{
|
||||||
|
list.Add(curNode.Page);
|
||||||
|
curNode = curNode.NextNode;
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
internal class PageNode
|
||||||
|
{
|
||||||
|
public int Page { get; set; }
|
||||||
|
public int[] Before { get; set; }
|
||||||
|
public PageNode? NextNode { get; set; }
|
||||||
|
|
||||||
|
public PageNode(int page, List<Rule> rules)
|
||||||
|
{
|
||||||
|
Page = page;
|
||||||
|
Before = rules.Count == 0 ? [int.MinValue] : rules.Select(r => r.before).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"{Page} << {Before}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsBefore(PageNode other)
|
||||||
|
{
|
||||||
|
if(Before.Any(b => b == other.Page))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
77
AdventOfCode/Problems/AOC2024/Day5/PrintQueue.cs
Normal file
77
AdventOfCode/Problems/AOC2024/Day5/PrintQueue.cs
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Rule = (int after, int before);
|
||||||
|
|
||||||
|
|
||||||
|
namespace AdventOfCode.Problems.AOC2024.Day5;
|
||||||
|
[ProblemInfo(2024, 5, "Print Queue")]
|
||||||
|
internal class PrintQueue : Problem<int, int>
|
||||||
|
{
|
||||||
|
private List<Rule> _rules = [];
|
||||||
|
private List<int[]> updates = [];
|
||||||
|
public override void CalculatePart1()
|
||||||
|
{
|
||||||
|
foreach (var update in updates)
|
||||||
|
{
|
||||||
|
if (IsOrdered(update, out _))
|
||||||
|
{
|
||||||
|
var mid = update[update.Length / 2];
|
||||||
|
Part1 += mid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsOrdered(int[] update, out List<int> orderd)
|
||||||
|
{
|
||||||
|
var list = new PageList(update, _rules);
|
||||||
|
orderd = list.Traverse();
|
||||||
|
return orderd.Zip(update).All(e => e.First== e.Second);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[] SortUpdates(int[] updates)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void CalculatePart2()
|
||||||
|
{
|
||||||
|
foreach (var update in updates)
|
||||||
|
{
|
||||||
|
if (!IsOrdered(update, out var ordered))
|
||||||
|
{
|
||||||
|
var mid = ordered[update.Length / 2];
|
||||||
|
Part2 += mid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void LoadInput()
|
||||||
|
{
|
||||||
|
var lines = ReadInputLines("input.txt");
|
||||||
|
|
||||||
|
var parsingPages = false;
|
||||||
|
foreach (var line in lines)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(line))
|
||||||
|
{
|
||||||
|
parsingPages = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (parsingPages)
|
||||||
|
{
|
||||||
|
updates.Add(line.Split(',').Select(int.Parse).ToArray());
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
var d = line.Split('|').Select(int.Parse);
|
||||||
|
_rules.Add((d.First(), d.Last()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user