@ -53,6 +53,8 @@ namespace AdventOfCode._2023
}
var finalizedSeedRanges = new List < SeedRange > ( ) ;
//Get our seed ranges
var values = inputs . First ( ) . First ( ) . Split ( ":" ) [ 1 ] . Trim ( ) . Split ( " " ) . Select ( x = > long . Parse ( x ) ) . ToArray ( ) ;
for ( int i = 0 ; i < values . Length ; i + = 2 )
{
@ -60,6 +62,7 @@ namespace AdventOfCode._2023
var endSeed = values [ i ] + values [ i + 1 ] - 1 ; //Minus one because it counts i
var seed = new SeedRange ( ) { Start = startSeed , End = endSeed } ;
Log ( $"Transforming seed range {seed.Start} - {seed.End}" ) ;
var prevType = MapType . SEED ;
var seedRanges = new List < SeedRange > ( ) { seed } ;
@ -68,20 +71,12 @@ namespace AdventOfCode._2023
Log ( $"Mapping from {prevType} to {mapType}" ) ;
var activeMap = maps . First ( x = > x . From = = prevType & & x . To = = mapType ) ;
seedRanges = activeMap . GetSeedRanges ( seedRanges ) ;
seedRanges . ForEach ( x = > Log ( $"Range: {x.Start} - {x.End}" ) ) ;
prevType = mapType ; //Denote our next mapping
}
finalizedSeedRanges = finalizedSeedRanges . Concat ( seedRanges ) . ToList ( ) ;
//var mapType = MapType.SOIL;
//var prevType = MapType.SEED;
//Log($"Mapping from {prevType} to {mapType}");
//var activeMap = maps.First(x => x.From == prevType && x.To == mapType);
//var postMapSeedRanges = activeMap.GetSeedRanges(seed);
//for (long x = startSeed ; x < endSeed; x++)
//{
// Console.WriteLine($"Seed {x} has a soil value of {activeMap.Transform(x)}");
//}
//activeMap.GetSeedRanges(seed);
//Add the output ranges to our total list to be minimized later
finalizedSeedRanges = finalizedSeedRanges . Concat ( seedRanges ) . ToList ( ) ;
}
this . Answer = finalizedSeedRanges . Min ( x = > x . Start ) ;
return this . _response ;
@ -136,24 +131,21 @@ namespace AdventOfCode._2023
return result ;
}
/// <summary>
/// Generate the given seed ranges for Part B with the large dataset
/// </summary>
/// <param name="ranges"></param>
/// <returns></returns>
public List < SeedRange > GetSeedRanges ( List < SeedRange > ranges )
{
//All valid return ranges for the given input seed range
var totalRanges = new List < SeedRange > ( ) ;
Console . WriteLine ( "###############" ) ;
foreach ( var range in ranges )
{
var seedRanges = new List < SeedRange > ( ) ;
var originalSeedRanges = new List < SeedRange > ( ) ;
//DEBUG
Console . WriteLine ( "\n" ) ;
//for (long i = range.Start; i <= range.End; i++)
//{
// Console.WriteLine($"Seed {i} has value of {Transform(i)}");
//}
//Ex) Range 55-67
foreach ( var mapData in _mapData )
{
// Check if any part of rangeA is within rangeB, or vice versa
@ -161,25 +153,25 @@ namespace AdventOfCode._2023
( range . End > = mapData . Source & & range . End < = mapData . SourceEnd ) | |
( mapData . Source > = range . Start & & mapData . Source < = range . End ) | |
( mapData . SourceEnd > = range . Start & & mapData . SourceEnd < = range . End ) ;
//EX) MapData: 50-98 with a range of 48 and a start of 52
//if (range.Start >= mapData.Source || range.End <= mapData.SourceEnd)
if ( isRangeWithinMapData )
{
var localizedRange = new SeedRange ( Math . Max ( 0 , range . Start - mapData . Source ) , Math . Min ( mapData . Range - 1 , range . End - mapData . Source ) /* - 1 Since we count the start number minus 1 */ ) ;
//For the end range, 92 - 50 = 42 but we do a -1 so why its 41 which is wrong
var inputStart = mapData . Source + localizedRange . Start ; //50 + 5 = 55
var inputEnd = mapData . Source + localizedRange . End ; //50 + 17 = 67
//Calculate the localized range in relation to the given range and the given map data
//Math.Max(0, range.Start - mapData.Source) - In the event the range start is below the start of the mapData, take 0 as that is within the range
// Math.Min(mapData.Range - 1, range.End - mapData.Source) - if the range extends past the bounds of mapData, take mapData -1. -1 is because we count the initial starting source in range
var localizedRange = new SeedRange ( Math . Max ( 0 , range . Start - mapData . Source ) , Math . Min ( mapData . Range - 1 , range . End - mapData . Source ) ) ;
//Calculate the Source values (we need this to track any values that aren't within our output bounds)
var inputStart = mapData . Source + localizedRange . Start ;
var inputEnd = mapData . Source + localizedRange . End ;
originalSeedRanges . Add ( new SeedRange ( )
{
Start = inputStart ,
End = inputEnd
} ) ;
var outputStart = mapData . Destination + localizedRange . Start ; //52 + 5 = 57
var outputEnd = mapData . Destination + localizedRange . End ; //52 + 17 = 69
//Calculate the valid output ranges for the given mapData (this is the actual transformation for the given ranges)
var outputStart = mapData . Destination + localizedRange . Start ;
var outputEnd = mapData . Destination + localizedRange . End ;
seedRanges . Add ( new SeedRange ( )
{
@ -189,11 +181,12 @@ namespace AdventOfCode._2023
}
}
//F or any of the seed ranges created that doesn't cover seed range, create a 1-1 mapping
//F Or all the ranges NOT covered by the original seed range, create a 1-1 mapping.
var validRangesNotFound = GetNonOverlappingRanges ( range , originalSeedRanges . OrderBy ( x = > x . Start ) . ToList ( ) ) ;
//Concat all of the seed ranges together
totalRanges = totalRanges . Concat ( seedRanges . Concat ( validRangesNotFound ) ) . OrderBy ( x = > x . Start ) . ToList ( ) ;
}
totalRanges . ForEach ( x = > Console . WriteLine ( $"Range of: {x.Start} to {x.End}" ) ) ;
return totalRanges ;
}