var lines = File.ReadAllLines("input.txt"); var pageOrderingRules = new List<(int, int)>(); var pageNumbersUpdates = new List>(); var separatorIndex = lines.ToList().IndexOf(string.Empty); for (var i = 0; i < separatorIndex; i++) { var parts = lines[i].Split('|'); pageOrderingRules.Add((int.Parse(parts[0]), int.Parse(parts[1]))); } for (var i = separatorIndex + 1; i < lines.Length; i++) { var currentList = lines[i].Split(',') .Select(int.Parse) .ToList(); pageNumbersUpdates.Add(currentList); } var part1 = 0; var part2 = 0; foreach (var pageNumberUpdate in pageNumbersUpdates) { var isInRightOder = true; for (var i = 0; i < pageNumberUpdate.Count; i++) { var rules = pageOrderingRules .Where(rule => rule.Item1 == pageNumberUpdate[i]) .ToList(); if (!IsPageInRightOrder(i, rules, pageNumberUpdate)) { isInRightOder = false; break; } } if (isInRightOder) { part1 += pageNumberUpdate[pageNumberUpdate.Count / 2]; } else { var orderedPages = OrderPages(pageNumberUpdate, pageOrderingRules); part2 += orderedPages[orderedPages.Count / 2]; } } Console.WriteLine($"Part1: {part1}\nPart2: {part2}"); List OrderPages( List pageNumberUpdate, List<(int, int)> rules) { var orderedPages = new List(pageNumberUpdate); bool changesMade; do { changesMade = false; foreach (var rule in rules) { if (!orderedPages.Contains(rule.Item1) || !orderedPages.Contains(rule.Item2)) continue; var index1 = orderedPages.IndexOf(rule.Item1); var index2 = orderedPages.IndexOf(rule.Item2); if (index1 <= index2) continue; orderedPages.RemoveAt(index1); orderedPages.Insert(index2, rule.Item1); changesMade = true; break; } } while (changesMade); return orderedPages; } bool IsPageInRightOrder(int pageIndex, List<(int, int)> rules, List pageNumberUpdate) { return rules.Select(rule => pageNumberUpdate.IndexOf(rule.Item2)).Where(indexOfRuleSecondPart => indexOfRuleSecondPart != -1).All(indexOfRuleSecondPart => pageIndex < indexOfRuleSecondPart); }