01020304050607080910111213141516171819202122232425

Advent of Code

2016/23

Safe Cracking

in C#

by encse

This is one of the top floors of the nicest tower in EBHQ. The Easter Bunny's private office is here, complete with a safe hidden behind a painting, and who wouldn't hide a star in a safe behind a painting?

The safe has a digital screen and keypad for code entry. A sticky note attached to the safe has a password hint on it: "eggs". The painting is of a large rabbit coloring some eggs. You see 7.

Read the full puzzle.

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

namespace AdventOfCode.Y2016.Day23;

[ProblemName("Safe Cracking")]
class Solution : Solver {

    public object PartOne(string input) => Solve(input, 7);
    public object PartTwo(string input) => Solve(input, 12);
    
    int Solve(string input, int a) {
        var prg = Parse(Patch(input));
        var regs = new Dictionary<string, int>();
        var ip = 0;
        int getReg(string reg) {
            return int.TryParse(reg, out var n) ? n
                : regs.ContainsKey(reg) ? regs[reg]
                : 0;
        }
        void setReg(string reg, int value) {
            if (!int.TryParse(reg, out var _)) {
                regs[reg] = value;
            }
        }

        setReg("a", a);

        while(ip < prg.Length){
            var stm = prg[ip];
            switch (stm[0]) {
                case "cpy":
                    setReg(stm[2], getReg(stm[1]));
                    ip++;
                    break;
                case "inc":
                    setReg(stm[1], getReg(stm[1]) + 1);
                    ip++;
                    break;
                case "mul":
                    setReg(stm[2], getReg(stm[1]) * getReg(stm[2]));
                    ip++;
                    break;
                case "dec":
                    setReg(stm[1], getReg(stm[1]) - 1);
                    ip++;
                    break;
                case "jnz":
                    ip += getReg(stm[1]) != 0 ? getReg(stm[2]) : 1;
                    break;
                case "tgl":
                    var ipDst = ip + getReg(stm[1]);
                    if (ipDst >= 0 && ipDst < prg.Length) {
                        var stmDst = prg[ipDst];
                        stmDst[0] = stmDst[0] switch {
                            "cpy" => "jnz",
                            "inc" => "dec",
                            "dec" => "inc",
                            "jnz" => "cpy",
                            "tgl" => "inc",
                            _ => stmDst[0]
                        };
                    }
                    ip++;
                    break;
                default: 
                    throw new Exception("Cannot parse " + string.Join(" ", stm));
            }
        }
        return getReg("a");
    }

    string Patch(string input) {
        var lines = input.Split('\n');
        lines[5] = "cpy c a";
        lines[6] = "mul d a";
        lines[7] = "cpy 0 d";
        lines[8] = "cpy 0 c";
        return string.Join("\n", lines);
    }
    
    string[][] Parse(string input) =>
        input.Split('\n').Select(line => line.Split(' ')).ToArray();
}

Please ☆ my repo if you like it!

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