#pragma warning disable
var input = File.ReadAllLines("../../../../Input.in")
.Select(line =>
{
var arr = line.Split(new[] { ',', '.', ' ', '=', 'x', 'y', 'z' }, StringSplitOptions.RemoveEmptyEntries);
var numbers = arr.Skip(1).Select(int.Parse).ToArray();
return new Cube(arr[0] == "on", numbers[0], numbers[1], numbers[2], numbers[3], numbers[4], numbers[5]);
}).ToArray();
var onCubes = new HashSet<(int, int, int)>();
foreach (var cube in input)
{
for (int x = Math.Max(cube.xMin, -50); x <= Math.Min(cube.xMax, 50); x++)
{
for (int y = Math.Max(cube.yMin, -50); y <= Math.Min(cube.yMax, 50); y++)
{
for (int z = Math.Max(cube.zMin, -50); z <= Math.Min(cube.zMax, 50); z++)
{
if (cube.on)
{
onCubes.Add((x, y, z));
}
else if (onCubes.Contains((x, y, z)))
{
onCubes.Remove((x, y, z));
}
}
}
}
}
Console.WriteLine("The initialization area has " + onCubes.Count + " cubes with the ON state");
Cube? Intersect(Cube a, Cube b, bool on)
{
if (a.xMin > b.xMax || a.xMax < b.xMin || a.yMin > b.yMax || a.yMax < b.yMin || a.zMin > b.zMax || a.zMax < b.zMin)
{
return null;
}
return new Cube(
on,
Math.Max(a.xMin, b.xMin),
Math.Min(a.xMax, b.xMax),
Math.Max(a.yMin, b.yMin),
Math.Min(a.yMax, b.yMax),
Math.Max(a.zMin, b.zMin),
Math.Min(a.zMax, b.zMax));
}
var resultingCubes = new List<Cube>();
foreach (var cube in input)
{
var cubesToAdd = new List<Cube>();
if (cube.on)
{
cubesToAdd.Add(cube);
}
foreach (var otherCube in resultingCubes)
{
var intersection = Intersect(cube, otherCube, !otherCube.on);
if (intersection != null)
{
cubesToAdd.Add(intersection.Value);
}
}
resultingCubes.AddRange(cubesToAdd);
}
long Volume(Cube c) => (c.xMax - c.xMin + 1L) * (c.yMax - c.yMin + 1L) * (c.zMax - c.zMin + 1L);
Console.WriteLine("There are " + resultingCubes.Aggregate(0L, (totalVolume, c) => totalVolume + Volume(c) * (c.on ? 1 : -1)) + " cubes with the ON state after the rebooting sequence");
record struct Cube(bool on, int xMin, int xMax, int yMin, int yMax, int zMin, int zMax);