MapParser.cs 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. using System.Collections.ObjectModel;
  2. using System.Text.RegularExpressions;
  3. namespace Day5;
  4. public partial class MapParser
  5. {
  6. [GeneratedRegex(@"\d+")]
  7. private partial Regex NumberList();
  8. public Almanac Parse(string inputFile)
  9. {
  10. using var reader = File.OpenText(inputFile);
  11. var almanac = new Almanac();
  12. var line = reader.ReadLine()!;
  13. if (!line.StartsWith("seeds:"))
  14. {
  15. throw new Exception("Expecting the first line to list the seeds");
  16. }
  17. foreach (Match m in NumberList().Matches(line.Substring(6)))
  18. {
  19. almanac.Seeds.Add(long.Parse(m.Value));
  20. }
  21. string source = string.Empty;
  22. while (!reader.EndOfStream)
  23. {
  24. line = reader.ReadLine()!;
  25. if (String.IsNullOrWhiteSpace(line))
  26. {
  27. line = reader.ReadLine()!;
  28. var parts = line.Split(new char[] {'-', ' '},
  29. StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
  30. if (parts.Length < 4)
  31. {
  32. throw new Exception($"Expected src-to-dst map line: {line}");
  33. }
  34. source = parts[0];
  35. var destination = parts[2];
  36. almanac.Mappings.Add((source, destination));
  37. }
  38. else
  39. {
  40. var numbers = NumberList().Matches(line).Cast<Match>().Select(x => long.Parse(x.Value)).ToList();
  41. if (numbers.Count != 3)
  42. {
  43. throw new Exception($"Expecting lines to contain exactly 3 numbers, but got: {line}");
  44. }
  45. if (!almanac.MappingData.ContainsKey(source))
  46. {
  47. almanac.MappingData[source] = new Collection<RangeMapping>();
  48. }
  49. almanac.MappingData[source].Add(new RangeMapping(numbers[1], numbers[0], numbers[2]));
  50. }
  51. }
  52. return almanac;
  53. }
  54. }