MapParser.cs 2.2 KB

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