Files
Project-AOC-2024/Day9/Program.cs
Dimitrios Kaltzidis ec9f8e03a0 Add Day 9
2024-12-09 18:24:29 +02:00

113 lines
2.8 KiB
C#

var diskMap = File.ReadAllText("input.txt");
var disk = GenerateFileSystem(diskMap); // I could create a class for this, but... meh
var part1 = DefragBlocks(new List<int>(disk.Item1));
var part2 = DefragFiles(new List<int>(disk.Item1), new List<(int Id, int Length, int Position)>(disk.Item2), disk.Item3);
Console.WriteLine($"Part1: {part1}\nPart2: {part2}");
long DefragFiles(List<int> fileSystem, List<(int Id, int Length, int Position)> files, List<(int Length, int Position)> free)
{
for (var i = files.Count - 1; i >= 0; i--)
{
var file = files[i];
for (var j = 0; j < free.Count; j++)
{
var slot = free[j];
if (file.Position < slot.Position)
{
break;
}
if (slot.Length >= file.Length)
{
for (var k = 0; k < file.Length; k++)
{
(fileSystem[slot.Position + k], fileSystem[file.Position + k]) = (fileSystem[file.Position + k], fileSystem[slot.Position + k]);
}
free[j] = (slot.Length - file.Length, slot.Position + file.Length);
break;
}
}
}
return CalculateChecksum(fileSystem);
}
long DefragBlocks(List<int> fileSystem)
{
(int left, int right) = (0, fileSystem.Count - 1);
while (left < right)
{
if (fileSystem[left] != -1)
{
left++;
}
else
{
if (fileSystem[right] == -1)
{
right--;
}
else
{
(fileSystem[left], fileSystem[right]) = (fileSystem[right], fileSystem[left]);
}
}
}
return CalculateChecksum(fileSystem);
}
long CalculateChecksum(List<int> fileSystem)
{
var checksum = 0L;
for (var i = 0; i < fileSystem.Count; i++)
{
var value = fileSystem[i];
if (value != -1)
{
checksum += value * i;
}
}
return checksum;
}
(List<int>, List<(int Id, int Length, int Position)>, List<(int Length, int Position)>) GenerateFileSystem(string diskMapDescription)
{
var file = true;
var fileSystem = new List<int>();
var freeSpace = new List<(int Length, int Position)>();
var files = new List<(int Id, int Length, int Position)>();
var id = 0;
foreach (var length in diskMapDescription.Select(c => int.Parse(c + "")))
{
var value = file ? id : -1;
var position = fileSystem.Count;
if (file)
{
files.Add((id, length, position));
id += 1;
}
else
{
freeSpace.Add((length, position));
}
for (int i = 0; i < length; i++)
{
fileSystem.Add(value);
}
file = !file;
}
return (fileSystem, files, freeSpace);
}