using System.Collections.ObjectModel; using System.Text.RegularExpressions; namespace Day5; public partial class MapParser { [GeneratedRegex(@"\d+")] private partial Regex NumberList(); public Almanac Parse(string inputFile) { using var reader = File.OpenText(inputFile); var almanac = new Almanac(); var line = reader.ReadLine()!; if (!line.StartsWith("seeds:")) { throw new Exception("Expecting the first line to list the seeds"); } foreach (Match m in NumberList().Matches(line.Substring(6))) { almanac.Seeds.Add(long.Parse(m.Value)); } string source = string.Empty; while (!reader.EndOfStream) { line = reader.ReadLine()!; if (String.IsNullOrWhiteSpace(line)) { line = reader.ReadLine()!; var parts = line.Split(new char[] {'-', ' '}, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries); if (parts.Length < 4) { throw new Exception($"Expected src-to-dst map line: {line}"); } source = parts[0]; var destination = parts[2]; almanac.Mappings.Add((source, destination)); } else { var numbers = NumberList().Matches(line).Cast().Select(x => long.Parse(x.Value)).ToList(); if (numbers.Count != 3) { throw new Exception($"Expecting lines to contain exactly 3 numbers, but got: {line}"); } if (!almanac.MappingData.ContainsKey(source)) { almanac.MappingData[source] = new Collection(); } almanac.MappingData[source].Add(new RangeMapping(numbers[1], numbers[0], numbers[2])); } } return almanac; } }