|
|
@@ -9,8 +9,8 @@ public class Almanac
|
|
|
public IList<(string Source, string Destination)> Mappings { get; } =
|
|
|
new List<(string Source, string Destination)>();
|
|
|
|
|
|
- public Dictionary<string, IList<Range>> MappingData { get; } =
|
|
|
- new Dictionary<string, IList<Range>>();
|
|
|
+ public Dictionary<string, IList<RangeMapping>> MappingData { get; } =
|
|
|
+ new Dictionary<string, IList<RangeMapping>>();
|
|
|
|
|
|
public IList<long> Map(IList<long> start, string source, string destination)
|
|
|
{
|
|
|
@@ -24,11 +24,49 @@ public class Almanac
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
+
|
|
|
+ public IList<Range> Map(IList<Range> ranges, string source, string destination)
|
|
|
+ {
|
|
|
+ var result = ranges;
|
|
|
+ var current = source;
|
|
|
+ while (current != destination)
|
|
|
+ {
|
|
|
+ var inQueue = new Queue<Range>(result);
|
|
|
+ result = new List<Range>();
|
|
|
+
|
|
|
+ while (inQueue.Count > 0)
|
|
|
+ {
|
|
|
+ var range = inQueue.Dequeue();
|
|
|
+ foreach (var rangeMapping in MappingData[current].Append(RangeMapping.Identity))
|
|
|
+ {
|
|
|
+ if (rangeMapping.IsWithin(range))
|
|
|
+ {
|
|
|
+ result.Add(rangeMapping.Transform(range));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (rangeMapping.IsOverlap(range))
|
|
|
+ {
|
|
|
+ foreach (var fragment in rangeMapping.Split(range))
|
|
|
+ {
|
|
|
+ inQueue.Enqueue(fragment);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Console.WriteLine($"{current} => {result.Count}");
|
|
|
+
|
|
|
+ current = Mappings.First(m => m.Source == current).Destination;
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
|
|
|
private IList<long> MapSingle(IList<long> start, string source)
|
|
|
{
|
|
|
return start
|
|
|
- .Select(num => MappingData[source].FirstOrDefault(x => x.IsMatch(num), Range.Identity).Transform(num))
|
|
|
+ .Select(num => MappingData[source].FirstOrDefault(x => x.IsMatch(num), RangeMapping.Identity).Transform(num))
|
|
|
.ToList();
|
|
|
}
|
|
|
}
|