138 lines
3.4 KiB
C#
138 lines
3.4 KiB
C#
using System.Numerics;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
|
|
// Main1();
|
|
Main2();
|
|
|
|
void Main1()
|
|
{
|
|
var data = LoadData1(Path.Join("..", "..", "09a.txt"));
|
|
int i = 0;
|
|
int j = data.Length - 1;
|
|
while (i < j)
|
|
{
|
|
if (data[i] == -1)
|
|
{
|
|
while (data[j] == -1)
|
|
j--;
|
|
data[i] = data[j];
|
|
data[j] = -1;
|
|
}
|
|
i++;
|
|
}
|
|
i--;
|
|
BigInteger checksum = 0;
|
|
while (i >= 0)
|
|
{
|
|
if (data[i] < 0)
|
|
throw new Exception($"Index {i} Value {data[i]}");
|
|
checksum += i * data[i];
|
|
i--;
|
|
}
|
|
Console.WriteLine($"Part1: {checksum,15}");
|
|
}
|
|
|
|
void Main2()
|
|
{
|
|
var (files, empties) = LoadData2(Path.Join("..", "..", "09a.txt"));
|
|
for (int i = files.Count-1; i >= 1; i--)
|
|
{
|
|
var file = files[i];
|
|
for (int j = 0; j < empties.Count; j++)
|
|
{
|
|
var empty = empties[j];
|
|
if (file.Location < empty.Location)
|
|
break;
|
|
if (file.Length <= empty.Length)
|
|
{
|
|
file.Location = empty.Location;
|
|
empties[j] = new(empty.Location + file.Length, empty.Length - file.Length);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
//long is big enough but changing it didn't help execution time so...
|
|
BigInteger checksum = 0;
|
|
foreach (var f in files)
|
|
{
|
|
for (int i = 0; i < f.Length; i++)
|
|
{
|
|
checksum += f.Id * (f.Location + i);
|
|
}
|
|
}
|
|
Console.WriteLine($"Part2: {checksum,15}");
|
|
}
|
|
|
|
int[] LoadData1(string filepath)
|
|
{
|
|
int next_id = 0;
|
|
bool next_is_blank = false;
|
|
int GetId()
|
|
{
|
|
if (next_is_blank)
|
|
{
|
|
next_is_blank = false;
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
next_is_blank = true;
|
|
return next_id++;
|
|
}
|
|
}
|
|
var data = File.ReadAllText(filepath).Trim().SelectMany(c => Enumerable.Repeat(GetId(), c - '0')).ToArray();
|
|
return data;
|
|
}
|
|
|
|
(List<Filelike>,List<Empty>) LoadData2(string filepath)
|
|
{
|
|
short next_id = 0;
|
|
bool next_is_blank = false;
|
|
int location = 0;
|
|
List<Filelike> files = [];
|
|
List<Empty> empties = [];
|
|
foreach (char c in File.ReadAllText(filepath).Trim())
|
|
{
|
|
int length = c - '0';
|
|
if (next_is_blank)
|
|
{
|
|
if (length > 0)
|
|
empties.Add(new (location, length));
|
|
next_is_blank = false;
|
|
location += length;
|
|
}
|
|
else
|
|
{
|
|
next_is_blank = true;
|
|
if (length > 0)
|
|
files.Add(new (location, length, next_id));
|
|
location += length;
|
|
next_id++;
|
|
}
|
|
}
|
|
return (files,empties);
|
|
}
|
|
|
|
class Filelike(int Location, int Length, short Id)
|
|
{
|
|
public int Location = Location;
|
|
public int Length = Length;
|
|
public short Id = Id;
|
|
}
|
|
class Empty(int Location, int Length)
|
|
{
|
|
public int Location = Location;
|
|
public int Length = Length;
|
|
}
|
|
|
|
// class Filelike(int Location, int Length, int Id)
|
|
// {
|
|
// public int Location = Location;
|
|
// public int Length = Length;
|
|
// public int Id = Id;
|
|
// }
|
|
// class Empty(int Location, int Length)
|
|
// {
|
|
// public int Location = Location;
|
|
// public int Length = Length;
|
|
// } |