Skip to content

Commit

Permalink
2024 Day 9
Browse files Browse the repository at this point in the history
  • Loading branch information
premun committed Dec 17, 2024
1 parent 9a9c0de commit 4a1d54d
Showing 1 changed file with 64 additions and 74 deletions.
138 changes: 64 additions & 74 deletions src/2024/09/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,99 +4,89 @@
.Select(c => c - '0')
.ToArray();

var debug = true;
var blocks = new LinkedList<Block>();
bool empty = false;

var forward = new BlockStream(diskMap);
var backward = new BlockStream(diskMap.Reverse());
var blockCount = diskMap.Length;
var fileBlockCount = blockCount / 2;
var position = 0;

ulong checksum = 0UL;
for (int i = 0; i < diskMap.Length; i++)
{
blocks.AddLast(!empty
? new FileBlock((i + 1) / 2, i, diskMap[i])
: new FreeBlock(i, diskMap[i]));
empty = !empty;
}

do
LinkedListNode<Block> end = blocks.Last!;
while(end != blocks.First)
{
if (forward.Current is FileBlock first)
LinkedListNode<Block> start = blocks.First!;
while (start != end)
{
StoreBlock(first.FileId);
forward.MoveNext();
continue;
}
if (end.Value is not FileBlock fileToMove)
{
end = end.Previous!;
continue;
}

if (backward.Current is not FileBlock last)
{
backward.MoveNext();
continue;
}
if (start.Value is not FreeBlock free || free.Size < fileToMove.Size)
{
start = start.Next!;
continue;
}

StoreBlock(fileBlockCount - last.FileId);
forward.MoveNext();
backward.MoveNext();
} while (forward.Current.BlockId < blockCount - backward.Current.BlockId - 1);
var newStart = start.Next;
blocks.AddBefore(start, new FileBlock(fileToMove.FileId, fileToMove.BlockId, fileToMove.Size));
free.Size -= fileToMove.Size;
if (free.Size == 0)
{
blocks.Remove(start);
}

if (debug) Console.Write('.');
var newEmptySpace = blocks.AddBefore(end, new FreeBlock(0, fileToMove.Size));

while (backward.Current is FileBlock f && f.Bit < diskMap[forward.Current.BlockId] - forward.Current.Bit)
{
StoreBlock(fileBlockCount - f.FileId);
backward.MoveNext();
}
start = blocks.First!;
end = end.Previous!;

Console.WriteLine();
Console.WriteLine($"Part 1: {checksum}");
Console.WriteLine($"Part 2: {""}");
blocks.Remove(newEmptySpace.Next!);

void StoreBlock(int fileId)
{
checksum += (ulong)(fileId * position);
position++;
if (debug) Console.Write((char)(fileId + '0'));
//Print();
}

end = end.Previous!;
}

file class BlockStream
ulong checksum = 0UL;
int id = 0;
foreach (var block in blocks)
{
protected readonly IEnumerator<int> _diskMap;
protected int _blockId;
protected int _fileId;
protected int _bit;
private bool _currentBlockIsFile = true;

public BlockStream(IEnumerable<int> diskMap)
if (block is not FileBlock f)
{
_diskMap = diskMap.GetEnumerator();
_bit = 0;
_diskMap.MoveNext();
id += block.Size;
continue;
}

public Block Current => _currentBlockIsFile
? new FileBlock(_fileId, _blockId, _bit)
: new FreeBlock(_blockId, _bit);

public bool MoveNext()
for (int j = 0; j < block.Size; j++)
{
_bit++;
checksum += (ulong)(id * f.FileId);
id++;
}
}

// Moving onto a new file block
while (_bit == _diskMap.Current)
{
if (!_diskMap.MoveNext())
{
return false;
}

_bit = 0;
_currentBlockIsFile = !_currentBlockIsFile;
if (_currentBlockIsFile)
{
_fileId++;
}
_blockId++;
}
Console.WriteLine(checksum);

return true;
void Print()
{
foreach (var block in blocks)
{
Console.Write(new string(block is FileBlock f ? (char)('0' + f.FileId) : '.', block.Size));
}
Console.WriteLine();
}

abstract file record Block(int BlockId, int Bit);
file record FileBlock(int FileId, int BlockId, int Bit) : Block(BlockId, Bit);
file record FreeBlock(int BlockId, int Bit) : Block(BlockId, Bit);
Console.WriteLine();

abstract file record Block(int BlockId, int Size)
{
public int Size { get; set; } = Size;
}
file record FileBlock(int FileId, int BlockId, int Size) : Block(BlockId, Size);
file record FreeBlock(int BlockId, int Size) : Block(BlockId, Size);

0 comments on commit 4a1d54d

Please sign in to comment.