var diskMap = File.ReadAllText("input.txt"); var disk = GenerateFileSystem(diskMap); // I could create a class for this, but... meh var part1 = DefragBlocks(new List(disk.Item1)); var part2 = DefragFiles(new List(disk.Item1), new List<(int Id, int Length, int Position)>(disk.Item2), disk.Item3); Console.WriteLine($"Part1: {part1}\nPart2: {part2}"); long DefragFiles(List 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 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 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, List<(int Id, int Length, int Position)>, List<(int Length, int Position)>) GenerateFileSystem(string diskMapDescription) { var file = true; var fileSystem = new List(); 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); }