Files
AdventOfCode/2023/Day05CSharp/Program.cs
2025-11-30 20:28:10 -05:00

173 lines
5.4 KiB
C#

// See https://aka.ms/new-console-template for more information
using AdventCommon;
using System.Collections;
using System.Net.Sockets;
var p1exampleSln = Part01("example-input.txt");
var p1puzzleSln = Part01("puzzle-input.txt");
Console.WriteLine("Part01 Example: " + p1exampleSln);
Console.WriteLine("Part01 Puzzle: " + p1puzzleSln);
long Part01(string fileName)
{
Day05Input d = new Day05Input(fileName);
List<long> locations = new List<long>();
long min = long.MaxValue;
foreach (var seed in d.Seeds)
{
long loc = Day05Input.MapEntry.GetConversion(seed.Number, d.Maps);
locations.Add(loc);
min = long.Min(loc, min);
}
return min;
}
class Day05Input : PuzzleInput
{
public class MapEntry
{
public MapEntry(string line)
{
var split = line.Split(' ', StringSplitOptions.RemoveEmptyEntries);
long dest = Int64.Parse(split[0]);
long source = Int64.Parse(split[1]);
long range = Int64.Parse(split[2]);
SourceRangeStart = source;
DestinationRangeStart = dest;
Range = range;
}
public MapEntry(long sourceStart, long destStart, long length)
{
SourceRangeStart = sourceStart;
DestinationRangeStart = destStart;
Range = length;
}
public long SourceRangeStart { get; private set; }
public long Range { get; private set; }
public long DestinationRangeStart { get; private set; }
public bool Contains(long val)
{
return (SourceRangeStart <= val && val < SourceRangeStart + Range);
}
public long GetDestinationCategory(long srcVal)
{
return DestinationRangeStart + (srcVal - SourceRangeStart);
}
public static long GetConversion(long val, List<MapEntry> entryMap)
{
foreach (var entry in entryMap)
{
if (entry.Contains(val))
{
return (val - entry.SourceRangeStart) + entry.DestinationRangeStart;
}
}
return val;
}
public static long GetConversion(long val, List<List<MapEntry>> Maps)
{
long currentVal = val;
foreach (var entry in Maps)
{
currentVal = GetConversion(currentVal, entry);
}
return currentVal;
}
}
public class Seed
{
public Seed(long number)
{
Number = number;
}
public long Number { get; private set; }
}
public List<Seed> Seeds { get; private set; } = new List<Seed>();
public List<MapEntry> SeedToSoil { get; private set; } = new List<MapEntry>();
public List<MapEntry> SoilToFertilizer { get; private set; } = new List<MapEntry>();
public List<MapEntry> FertilizerToWater { get; private set; } = new List<MapEntry>();
public List<MapEntry> WaterToLight { get; private set; } = new List<MapEntry>();
public List<MapEntry> LightToTemperature { get; private set; } = new List<MapEntry>();
public List<MapEntry> TemperatureToHumidity { get; private set; } = new List<MapEntry>();
public List<MapEntry> HumidityToLocation { get; private set; } = new List<MapEntry>();
public List<List<MapEntry>> Maps { get; private set; } = new List<List<MapEntry>>();
public Day05Input(string fileName, bool isPart02 = false) : base(fileName, false)
{
Maps.Add(SeedToSoil);
Maps.Add(SoilToFertilizer);
Maps.Add(FertilizerToWater);
Maps.Add(WaterToLight);
Maps.Add(LightToTemperature);
Maps.Add(TemperatureToHumidity);
Maps.Add(HumidityToLocation);
int currentMap = -1;
foreach (var line in Lines)
{
// Read the seeds line
if (Seeds.Count == 0)
{
// First line is seeds
if (!line.Split(':')[0].Equals("seeds"))
{
throw new InvalidDataException("Expected seeds");
}
if (!isPart02)
{
var seeds = line.Split(':')[1].Split(' ', StringSplitOptions.RemoveEmptyEntries);
foreach (var seed in seeds)
{
Seeds.Add(new Seed(Int64.Parse(seed)));
}
}
else
{
var seeds = line.Split(':')[1].Split(' ', StringSplitOptions.RemoveEmptyEntries);
if (!(seeds.Length % 2 == 0)) throw new InvalidDataException("Uneven seed count");
for (int i = 0; i < seeds.Length; i+=2)
{
}
}
continue;
}
if (String.IsNullOrWhiteSpace(line)) continue;
if (line.Contains("map:"))
{
// Move to the next map
currentMap++;
}
else
{
Maps[currentMap].Add(new MapEntry(line));
}
}
}
}