using System; using System.Collections.Generic; using System.Linq; using System.Reflection.Emit; using System.Text; using System.Threading.Tasks; using System.Text.RegularExpressions; namespace Advent24 { internal class Day5 { private static void IngestRule(String rule, Dictionary> ruleDict) { var ruleArray = rule.Split('|'); var ruleArrayInt32 = Array.ConvertAll(ruleArray, System.Convert.ToInt32); // if the ruleDict index doesn't already exists, add an empty list to it ruleDict.TryAdd(ruleArrayInt32[0], new List<(int, int)>(2)); ruleDict[ruleArrayInt32[0]].Add((ruleArrayInt32[0], ruleArrayInt32[1])); ruleDict.TryAdd(ruleArrayInt32[1], new List<(int, int)>(2)); ruleDict[ruleArrayInt32[1]].Add((ruleArrayInt32[0], ruleArrayInt32[1])); } private static void IngestPageRow(String pageRow, List> pageRowDictsList) { var pageRowArray = pageRow.Split(','); var pageRowArrayInt32 = Array.ConvertAll(pageRowArray, System.Convert.ToInt32); pageRowDictsList.Add(new Dictionary(pageRowArray.Length)); Int32 pageRowIndex = 1; foreach (var pageInt32 in pageRowArrayInt32) { pageRowDictsList[pageRowDictsList.Count - 1].Add(pageInt32, pageRowIndex); pageRowIndex++; } } private static Int32 GetPageRowMiddle(Dictionary pageRowDict) { var pageRowMiddleEnumerable = pageRowDict.Where(keyValuePair => keyValuePair.Value == (pageRowDict.Count + 1) / 2); return pageRowMiddleEnumerable.ElementAt(0).Key; } private static Boolean PageRowIsCorrect(Dictionary pageRowDict, Dictionary> ruleDict) { Boolean pageRowIsCorrect = true; foreach(Int32 page in pageRowDict.Keys) { if (ruleDict.TryGetValue(page, out List<(int, int)>? rules)) { foreach (var rule in rules) { // check if the rule pertains to our pageRow if(pageRowDict.TryGetValue(rule.Item1, out Int32 leftHandIndex) && pageRowDict.TryGetValue(rule.Item2, out Int32 rightHandIndex)) // if rule violation detected, set pageRowIsCorrect to false // and break as we don't need to check the rest of the pageRow if (leftHandIndex >= rightHandIndex) { pageRowIsCorrect = false; break; } } // break out of outer foreach loop if nner foreach // was broken due to finding a rule violation if (!pageRowIsCorrect) break; } } return pageRowIsCorrect; } private static Int32 GetCorrectMiddlesSum(Dictionary> ruleDict, List> pageRowDictsList) { Int32 correctMiddlesSum = 0; foreach (var pageRowDict in pageRowDictsList) { if (PageRowIsCorrect(pageRowDict, ruleDict)) { correctMiddlesSum += GetPageRowMiddle(pageRowDict); } } return correctMiddlesSum; } private static void CorrectPageRow(out Dictionary correctedPageRowDict, Dictionary pageRowDict, Dictionary> ruleDict) { correctedPageRowDict = pageRowDict.ToDictionary(); Boolean correctionWasRequired; do { correctionWasRequired = false; foreach (Int32 page in pageRowDict.Keys) { if (ruleDict.TryGetValue(page, out List<(int, int)>? rules)) { foreach (var rule in rules) { // check if the rule pertains to our pageRow if (correctedPageRowDict.TryGetValue(rule.Item1, out Int32 leftHandIndex) && correctedPageRowDict.TryGetValue(rule.Item2, out Int32 rightHandIndex)) // if rule violation detected, swap the positions if (leftHandIndex >= rightHandIndex) { // swap indices, i.e., swap positions correctedPageRowDict[rule.Item1] = rightHandIndex; correctedPageRowDict[rule.Item2] = leftHandIndex; correctionWasRequired = true; } } } } } while(correctionWasRequired); } private static Int32 GetCorrectedMiddlesSum(Dictionary> ruleDict, List> pageRowDictsList) { Int32 correctMiddlesSum = 0; foreach (var pageRowDict in pageRowDictsList) { if (!PageRowIsCorrect(pageRowDict, ruleDict)) { CorrectPageRow(out Dictionary correctedPageRowDict, pageRowDict, ruleDict); correctMiddlesSum += GetPageRowMiddle(correctedPageRowDict); } } return correctMiddlesSum; } public Day5() { String fileData = System.IO.File.ReadAllText(@"..\..\..\inputd5.txt"); var rulesAndPageRowsArray = fileData.Split('\n'); // indicates when we stop ingesting rules and start ingesting page rows Boolean amIngestingRules = true; // a dictionary to map from a page number to a rule containing that page number // the rule is that p1 must appear before p2 if the Tuple is (p1, p2), i.e., // index of p1 must be less than index of p2 Dictionary> ruleDict = []; // a dictionary to map from a page number to its position in the array List> pageRowDictsList = []; Int32 sumOfCorrectMiddles; Int32 sumOfCorrectedMiddles; foreach (var ruleOrPageRow in rulesAndPageRowsArray) { // empty line indicates end of rules and beginning of page rows if (ruleOrPageRow == "") { amIngestingRules = false; continue; } if(amIngestingRules) { IngestRule(ruleOrPageRow, ruleDict); } else { // am ingesting page rows now IngestPageRow(ruleOrPageRow, pageRowDictsList); } } sumOfCorrectMiddles = GetCorrectMiddlesSum(ruleDict, pageRowDictsList); sumOfCorrectedMiddles = GetCorrectedMiddlesSum(ruleDict, pageRowDictsList); Console.WriteLine("sumOfCorrectMiddles = {0:d}", sumOfCorrectMiddles); Console.WriteLine("sumOfCorrectedMiddles = {0:d}", sumOfCorrectedMiddles); // to keep the console window from closing Console.ReadKey(); } } }