Almanac.cs 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. using System.Collections.Generic;
  2. namespace Day5;
  3. public class Almanac
  4. {
  5. public IList<long> Seeds { get; } = new List<long>();
  6. public IList<(string Source, string Destination)> Mappings { get; } =
  7. new List<(string Source, string Destination)>();
  8. public Dictionary<string, IList<RangeMapping>> MappingData { get; } =
  9. new Dictionary<string, IList<RangeMapping>>();
  10. public IList<long> Map(IList<long> start, string source, string destination)
  11. {
  12. var result = start;
  13. var current = source;
  14. while (current != destination)
  15. {
  16. result = MapSingle(result, current);
  17. current = Mappings.First(m => m.Source == current).Destination;
  18. }
  19. return result;
  20. }
  21. public IList<Range> Map(IList<Range> ranges, string source, string destination)
  22. {
  23. var result = ranges;
  24. var current = source;
  25. while (current != destination)
  26. {
  27. var inQueue = new Queue<Range>(result);
  28. result = new List<Range>();
  29. while (inQueue.Count > 0)
  30. {
  31. var range = inQueue.Dequeue();
  32. foreach (var rangeMapping in MappingData[current].Append(RangeMapping.Identity))
  33. {
  34. if (rangeMapping.IsWithin(range))
  35. {
  36. result.Add(rangeMapping.Transform(range));
  37. break;
  38. }
  39. if (rangeMapping.IsOverlap(range))
  40. {
  41. foreach (var fragment in rangeMapping.Split(range))
  42. {
  43. inQueue.Enqueue(fragment);
  44. }
  45. break;
  46. }
  47. }
  48. }
  49. Console.WriteLine($"{current} => {result.Count}");
  50. current = Mappings.First(m => m.Source == current).Destination;
  51. }
  52. return result;
  53. }
  54. private IList<long> MapSingle(IList<long> start, string source)
  55. {
  56. return start
  57. .Select(num => MappingData[source].FirstOrDefault(x => x.IsMatch(num), RangeMapping.Identity).Transform(num))
  58. .ToList();
  59. }
  60. }