Skip to content

Commit 744cb16

Browse files
committed
2024 Day 9
1 parent 67ce530 commit 744cb16

File tree

1 file changed

+114
-2
lines changed

1 file changed

+114
-2
lines changed

src/2024/09/Program.cs

Lines changed: 114 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,118 @@
11
using AdventOfCode.Common;
22

3-
var lines = Resources.GetInputFileLines();
3+
int[] diskMap = Resources.GetInputFileLines().First()
4+
.Select(c => c - '0')
5+
.ToArray();
46

5-
Console.WriteLine($"Part 1: {""}");
7+
var forwardStream = new BlockStream(diskMap);
8+
var backwardStream = new ReverseBlockStream(diskMap);
9+
10+
ulong checksum = 0UL;
11+
var next = forwardStream.GetNext()!;
12+
var last = backwardStream.GetNext()!;
13+
int position = 0;
14+
15+
var debug = true;
16+
17+
while (next.Id < last.Id)
18+
{
19+
while (next is FileBlock)
20+
{
21+
checksum += (ulong)(next.Id * position);
22+
position++;
23+
//Console.WriteLine($"{next.Id} * {position}");
24+
if (debug) Console.Write((char)(next.Id + '0'));
25+
next = forwardStream.GetNext();
26+
}
27+
28+
while (last is FreeBlock)
29+
{
30+
last = backwardStream.GetNext();
31+
}
32+
33+
checksum += (ulong)(last.Id * position);
34+
position++;
35+
//Console.WriteLine($"{last.Id} * {position}");
36+
if (debug) Console.Write((char)(last.Id + '0'));
37+
38+
next = forwardStream.GetNext();
39+
last = backwardStream.GetNext();
40+
}
41+
42+
if (debug) Console.Write('.');
43+
44+
// We ended up somewhere in a single file block, we need to process it
45+
if (next is FileBlock)
46+
{
47+
// TODO: This could be better - we could make the pointers meet inside the block
48+
var sum = 0UL;
49+
for (int i = 0; i < diskMap.Length; i += 2)
50+
sum += (ulong)diskMap[i];
51+
52+
for (ulong i = (ulong)position; i < sum; ++i)
53+
{
54+
checksum += (ulong)(last.Id * position);
55+
position++;
56+
if (debug) Console.Write((char)(last.Id + '0'));
57+
}
58+
}
59+
60+
Console.WriteLine();
61+
62+
Console.WriteLine($"Part 1: {checksum}");
663
Console.WriteLine($"Part 2: {""}");
64+
65+
file class BlockStream
66+
{
67+
private readonly IEnumerator<int> _diskMap;
68+
protected int _id;
69+
private int _bit;
70+
private bool _currentBlockIsFile = true;
71+
72+
public BlockStream(IEnumerable<int> diskMap)
73+
{
74+
_diskMap = diskMap.GetEnumerator();
75+
_id = 0;
76+
_diskMap.MoveNext();
77+
_bit = _diskMap.Current;
78+
}
79+
80+
public Block GetNext()
81+
{
82+
while (_bit == 0)
83+
{
84+
if (!_diskMap.MoveNext())
85+
{
86+
return new FreeBlock(Id, int.MaxValue);
87+
}
88+
89+
_currentBlockIsFile = !_currentBlockIsFile;
90+
_bit = _diskMap.Current;
91+
92+
if (_currentBlockIsFile)
93+
{
94+
_id++;
95+
}
96+
}
97+
98+
_bit--;
99+
return _currentBlockIsFile
100+
? new FileBlock(Id, _diskMap.Current)
101+
: new FreeBlock(Id, _diskMap.Current);
102+
}
103+
104+
protected virtual int Id => _id;
105+
}
106+
107+
file class ReverseBlockStream(int[] diskMap)
108+
: BlockStream(diskMap.Reverse())
109+
{
110+
private readonly int _maxId = diskMap.Length / 2;
111+
112+
protected override int Id => _maxId - _id;
113+
public override int Rest => _bit;
114+
}
115+
116+
abstract file record Block(int Id, int Size);
117+
file record FileBlock(int Id, int Size) : Block(Id, Size);
118+
file record FreeBlock(int Id, int Size) : Block(Id, Size);

0 commit comments

Comments
 (0)