01020304050607080910111213141516171819202122232425

Advent of Code

2021/24

Arithmetic Logic Unit

in C#

by encse

Magic smoke starts leaking from the submarine's arithmetic logic unit (ALU). Without the ability to perform basic arithmetic and logic functions, the submarine can't produce cool patterns with its Christmas lights!

It also can't navigate. Or run the oxygen system.

Read the full puzzle.

using System;
using System.Linq;
using System.Collections.Generic;

namespace AdventOfCode.Y2021.Day24;

[ProblemName("Arithmetic Logic Unit")]
class Solution : Solver {

    public object PartOne(string input) => GetSerials(input).max;
    public object PartTwo(string input) => GetSerials(input).min;

    (string min, string max) GetSerials(string input) {

        var digits = Enumerable.Range(1, 9).ToArray();

        // The input has 14 code blocks, each dealing with one digit.
        // The blocks define 7 pairs of `a`, `b` digits and a `shift` between them.
        // The input is valid if for each pair the condition `a + shift = b` holds.
        var stmBlocks = input.Split("inp w\n")[1..]; 

        // Extracts the numeric argument of a statement:
        var getArgFromLine = (int iblock, Index iline) =>   
            int.Parse(stmBlocks[iblock].Split('\n')[iline].Split(' ')[^1]);

        // A stack will contain the index of an `a` digit when we find its corresponding `b`.
        var stack = new Stack<int>();
       
        // We will fill up the result when `b` is found.
        var max = Enumerable.Repeat(int.MinValue, 14).ToArray();
        var min = Enumerable.Repeat(int.MaxValue, 14).ToArray();
        
        for (var j = 0; j < 14; j++) {
            if (stmBlocks[j].Contains("div z 1")) { 
                // j points to an `a` digit.
                stack.Push(j);
            } else { 
                // j points to a `b` digit. 
              
                // `a` is at i.
                var i = stack.Pop(); 

                // A part of shift is hidden in each of the two blocks:
                var shift = getArgFromLine(i, ^4) + getArgFromLine(j, 4);

                // Find the best a and b so that the equation holds
                foreach (var a in digits) {

                    var b = a + shift;

                    if (digits.Contains(b)) {
                        if (a > max[i]) {
                            (max[i], max[j]) = (a, b);
                        }
                        if (a < min[i]) {
                            (min[i], min[j]) = (a, b);
                        }
                    }
                }
            }
        }

        // That's all folks
        return (string.Join("", min), string.Join("", max));
    }
}

Please ☆ my repo if you like it!

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