01020304050607080910111213141516171819202122232425

Advent of Code

2021/22

Reactor Reboot

in C#

by encse

Operating at these extreme ocean depths has overloaded the submarine's reactor; it needs to be rebooted.

The reactor core is made up of a large 3-dimensional grid made up entirely of cubes, one cube per integer 3-dimensional coordinate (x,y,z). Each cube can be either on or off; at the start of the reboot process, they are all off. (Could it be an old model of a reactor you've seen before?)

Read the full puzzle.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace AdventOfCode.Y2021.Day22;

[ProblemName("Reactor Reboot")]
class Solution : Solver {

    public object PartOne(string input) => ActiveCubesInRange(input, 50);
    public object PartTwo(string input) => ActiveCubesInRange(input, int.MaxValue);

    public long ActiveCubesInRange(string input, int range) {
        var cmds = Parse(input);

        // Recursive approach

        // If we can determine the number of active cubes in subregions
        // we can compute the effect of the i-th cmd as well:
        long activeCubesAfterIcmd(int icmd, Region region) {

            if (region.IsEmpty || icmd < 0) {
                return 0; // empty is empty
            } else {
                var intersection = region.Intersect(cmds[icmd].region);
                var activeInRegion = activeCubesAfterIcmd(icmd - 1, region);
                var activeInIntersection = activeCubesAfterIcmd(icmd - 1, intersection);
                var activeOutsideIntersection = activeInRegion - activeInIntersection;

                // outside the intersection is unaffected, the rest is either on or off:
                return cmds[icmd].turnOff ? activeOutsideIntersection : activeOutsideIntersection + intersection.Volume;
            }
        }

        return activeCubesAfterIcmd(
            cmds.Length - 1,
            new Region(
                new Segment(-range, range),
                new Segment(-range, range),
                new Segment(-range, range)));
    }

    Cmd[] Parse(string input) {
        var res = new List<Cmd>();
        foreach (var line in input.Split("\n")) {
            var turnOff = line.StartsWith("off");
            // get all the numbers with a regexp:
            var m = Regex.Matches(line, "-?[0-9]+").Select(m => int.Parse(m.Value)).ToArray();
            res.Add(new Cmd(turnOff, new Region(new Segment(m[0], m[1]), new Segment(m[2], m[3]), new Segment(m[4], m[5]))));
        }
        return res.ToArray();
    }
}

record Cmd(bool turnOff, Region region);

record Segment(int from, int to) {
    public bool IsEmpty => from > to;
    public long Length => IsEmpty ? 0 : to - from + 1;

    public Segment Intersect(Segment that) =>
        new Segment(Math.Max(this.from, that.from), Math.Min(this.to, that.to));
}

record Region(Segment x, Segment y, Segment z) {
    public bool IsEmpty => x.IsEmpty || y.IsEmpty || z.IsEmpty;
    public long Volume => x.Length * y.Length * z.Length;

    public Region Intersect(Region that) =>
        new Region(this.x.Intersect(that.x), this.y.Intersect(that.y), this.z.Intersect(that.z));
}

Please ☆ my repo if you like it!

© 2025 Advent of Code is a registered trademark in the US Images provided by Bing image creator