예제 #1
0
        public static long CalcWithInput(int verb, int noun, long[] memory, Action <string, long, long> outputFunc)
        {
            memory[1] = verb;
            memory[2] = noun;
            var st = new MachineStatus {
                ProgramCounter = 0, RelativeBase = 0
            };

            return(Calc(st, memory, new long[0], outputFunc).Result);
        }
예제 #2
0
        public static bool CalcTwoScript(string script)
        {
            var scr = (script + "RUN\n").ToCharArray().Select(c => (long)c).ToArray();
            var asm = new long[2500];

            Day21Input.Day21Code.CopyTo(asm, 0);
            var st   = new MachineStatus();
            var outp = new List <long>();

            Machine.Calc(st, asm, scr, (a, b, c) => outp.Add(c));
            var str = new string(outp.Where(x => x < 256).Select(x => (char)x).ToArray());

            Console.WriteLine(str);
            if (str.Contains("Didn"))
            {
                return(false);
            }
            else
            {
                Console.WriteLine(outp.First(c => c > 256));
                return(true);
            }
        }
예제 #3
0
        public static MachineStatus Calc(MachineStatus st, long[] memory, long[] Inputs, Action <string, long, long> outputFunc, CalcMode calcMode = default)
        {
            var  outputAcc    = "";
            int  inputCounter = 0;
            long relativeBase = st.RelativeBase;
            long pc           = st.ProgramCounter;

            while (pc < memory.Length)
            {
                var opcode   = memory[pc] % 100;
                var arg1Mode = ArgMode(memory[pc], 100);
                var arg2Mode = ArgMode(memory[pc], 1000);
                var arg3Mode = ArgMode(memory[pc], 10000);
                long getArg1()
                {
                    switch (opcode)
                    {
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                    case 9:
                        var  addr = memory[pc + 1];
                        long arg  = addr;
                        if (arg1Mode == 0)
                        {
                            arg = memory[addr];
                        }
                        if (arg1Mode == 2)
                        {
                            arg = memory[addr + relativeBase];
                        }
                        return(arg);
                    }

                    return(0);
                }

                long getArg2()
                {
                    switch (opcode)
                    {
                    case 1:
                    case 2:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                        var  addr = memory[pc + 2];
                        long arg  = addr;
                        if (arg2Mode == 0)
                        {
                            arg = memory[addr];
                        }
                        if (arg2Mode == 2)
                        {
                            arg = memory[addr + relativeBase];
                        }
                        return(arg);
                    }

                    return(0);
                }

                long getArg3()
                {
                    switch (opcode)
                    {
                    case 7:
                    case 8:
                        var  addr = memory[pc + 3];
                        long arg  = addr;

                        if (arg3Mode == 2)
                        {
                            arg = memory[addr + relativeBase];
                        }

                        return(arg);
                    }

                    return(0);
                }

                var arg1 = getArg1();
                var arg2 = getArg2();
                var arg3 = getArg3();
                switch (opcode)
                {
                case 1:
                    var addrt = memory[pc + 3];
                    if (arg3Mode == 2)
                    {
                        addrt = addrt + relativeBase;
                    }
                    memory[addrt] = arg1 + arg2;
                    pc            = pc + 4;
                    break;

                case 2:
                    addrt = memory[pc + 3];
                    if (arg3Mode == 2)
                    {
                        addrt = addrt + relativeBase;
                    }
                    memory[addrt] = arg1 * arg2;
                    pc            = pc + 4;
                    break;

                case 3:
                    var addr31 = memory[pc + 1];
                    if (arg1Mode == 2)
                    {
                        addr31 = relativeBase + addr31;
                    }
                    memory[addr31] = Inputs[inputCounter++];
                    pc             = pc + 2;
                    if (calcMode == CalcMode.RunToFirstInput)
                    {
                        return new MachineStatus {
                                   Result = -240174, ProgramCounter = pc, RelativeBase = relativeBase, RanToHalt = false
                        }
                    }
                    ;
                    break;

                case 4:
                    arg1 = getArg1();
                    outputFunc("Output {0} {1}", pc, arg1);
                    pc         = pc + 2;
                    outputAcc += (char)arg1;

                    /*
                     * if (outputAcc.Contains("Didn"))
                     *      return new MachineStatus { Result = -1, ProgramCounter = pc, RelativeBase = relativeBase, RanToHalt = false };
                     */
                    if (calcMode == CalcMode.RunToFirstOutput)
                    {
                        return new MachineStatus {
                                   Result = arg1, ProgramCounter = pc, RelativeBase = relativeBase, RanToHalt = false
                        }
                    }
                    ;
                    break;

                case 5:                         //JNZ
                    if (arg1 != 0)
                    {
                        pc = arg2;
                    }
                    else
                    {
                        pc = pc + 3;
                    }
                    break;

                case 6:                         //JZ
                    if (arg1 == 0)
                    {
                        pc = arg2;
                    }
                    else
                    {
                        pc = pc + 3;
                    }
                    break;

                case 7:                         //LT
                    addrt = memory[pc + 3];
                    if (arg3Mode == 2)
                    {
                        addrt = addrt + relativeBase;
                    }
                    if (arg1 < arg2)
                    {
                        memory[addrt] = 1;
                    }
                    else
                    {
                        memory[addrt] = 0;
                    }
                    pc = pc + 4;
                    break;

                case 8:                         //EQ
                    addrt = memory[pc + 3];
                    if (arg3Mode == 2)
                    {
                        addrt = addrt + relativeBase;
                    }
                    if (arg1 == arg2)
                    {
                        memory[addrt] = 1;
                    }
                    else
                    {
                        memory[addrt] = 0;
                    }
                    pc = pc + 4;
                    break;

                case 9:                         //Set Relative Base
                    relativeBase += arg1;
                    pc           += 2;
                    break;

                case 99:
                    return(new MachineStatus {
                        Result = memory[0], ProgramCounter = pc, RelativeBase = relativeBase, RanToHalt = true
                    });
                }
            }
            return(new MachineStatus {
                Result = -230771, ProgramCounter = pc, RelativeBase = relativeBase, RanToHalt = false
            });
        }
예제 #4
0
 public static MachineStatus RunToOutput(MachineStatus st, long[] memory, Action <string, long, long> outputFunc)
 {
     return(Calc(st, memory, new long[0], outputFunc, CalcMode.RunToFirstOutput));
 }
예제 #5
0
 public static MachineStatus RunToOutput(MachineStatus st, long[] memory)
 {
     return(Calc(st, memory, new long[0], (s, l, arg3) => { }, CalcMode.RunToFirstOutput));
 }
예제 #6
0
 public static MachineStatus RunToInput(MachineStatus st, long[] memory, int singleInput, Action <string, long, long> outputFunc)
 {
     return(Calc(st, memory, new long[] { singleInput }, outputFunc, CalcMode.RunToFirstInput));
 }
예제 #7
0
 public static MachineStatus RunToInput(MachineStatus st, long[] memory, int singleInput)
 {
     return(Calc(st, memory, new long[] { singleInput }, (s, l, arg3) => { }, CalcMode.RunToFirstInput));
 }