using Spectre.Console; namespace AdventOfCode.Days; public class Day5 : Day { public override int Number => 5; public override string Name => "Cafeteria"; public override void RunPart1(bool display = true) { var freshIngredients = 0; var idRanges = new List(); var readingRanges = true; foreach (var line in Input.EnumerateLines()) { // Read ranges if (readingRanges) { // End of ranges if (line.IsWhiteSpace()) { readingRanges = false; continue; } var rangeSeparatorIndex = line.IndexOf('-'); var lower = long.Parse(line[..rangeSeparatorIndex]); var upper = long.Parse(line[(rangeSeparatorIndex + 1)..]); idRanges.Add(new IdRange(lower, upper)); } else { // Read ingredients var ingredientId = long.Parse(line); if (idRanges.Any(range => ingredientId >= range.Lower && ingredientId <= range.Upper)) { freshIngredients++; } } } if (display) { AnsiConsole.MarkupLine($"[green]Fresh ingredients count: [yellow]{freshIngredients}[/][/]"); } } public override void RunPart2(bool display = true) { var idRanges = new List(); var rangesToDelete = new List(); // Read ranges foreach (var line in Input.EnumerateLines()) { // End of ranges if (line.IsWhiteSpace()) { break; } var rangeSeparatorIndex = line.IndexOf('-'); var lower = long.Parse(line[..rangeSeparatorIndex]); var upper = long.Parse(line[(rangeSeparatorIndex + 1)..]); // Simplify ranges if there is overlap rangesToDelete.Clear(); var skipRange = false; foreach (var idRange in idRanges) { // Distinct if (lower > idRange.Upper || upper < idRange.Lower) { continue; } // Outer overlap if (lower >= idRange.Lower && upper <= idRange.Upper) { skipRange = true; break; } // Inner overlap if (lower <= idRange.Lower && upper >= idRange.Upper) { rangesToDelete.Add(idRange); } // Left overlap if (lower >= idRange.Lower && lower <= idRange.Upper) { lower = idRange.Lower; rangesToDelete.Add(idRange); } // Right overlap if (upper >= idRange.Lower && upper <= idRange.Upper) { upper = idRange.Upper; rangesToDelete.Add(idRange); } } if (!skipRange) { foreach (var idRange in rangesToDelete) { idRanges.Remove(idRange); } idRanges.Add(new IdRange(lower, upper)); } } var freshIngredients = idRanges.Sum(range => (range.Upper - range.Lower) + 1); if (display) { AnsiConsole.MarkupLine($"[green]Fresh ingredients count: [yellow]{freshIngredients}[/][/]"); } } private record struct IdRange(long Lower, long Upper); }