Beispiel #1
0
        private long GetInput()
        {
            if (Inputs.Count == 0 && DefaultInput.HasValue)
            {
                return(DefaultInput.Value);
            }

            return(Inputs.Dequeue());
        }
Beispiel #2
0
        private long GetNextInput()
        {
            while (!Exited)
            {
                lock (InputLock)
                {
                    if (Inputs.Count > 0)
                    {
                        Paused = false;
                        return(Inputs.Dequeue());
                    }
                    else if (DefaultInput.HasValue)
                    {
                        return(DefaultInput.Value);
                    }
                }
                Paused = true;
                Thread.Sleep(1);
            }

            throw new InterruptedWhileAwaitingInputError();
        }
Beispiel #3
0
        private long[] GetParams(long instruction, int PC, Operation op)
        {
            long[] res;
            Mode[] modes = GetModes((int)(instruction / 100));
            long   immediate;

            switch (op)
            {
            case Operation.Add:
            case Operation.Multiply:
            case Operation.LessThan:
            case Operation.TestEquals:
                res = new long[3];     //Let's just assume that any operation can take 3 params except reading input (must wait for input) and Halting
                for (int i = 0; i < 3; i++)
                {
                    try
                    {
                        immediate = (int)WorkingProgram[PC + i + 1];
                        if (modes[i] == Mode.Position && i != 2)     //If it's the output location, we still need teh "immediate" value
                        {
                            res[i] = WorkingProgram[(int)immediate];
                        }
                        else if (modes[i] == Mode.Relative)
                        {
                            if (i == 2)
                            {
                                res[i] = (int)immediate + RelativeBase;
                            }
                            else
                            {
                                res[i] = WorkingProgram[(int)immediate + RelativeBase];
                            }
                        }
                        else if (modes[i] == Mode.Immediate || i == 2)
                        {
                            res[i] = immediate;
                        }
                        else
                        {
                            throw new Exception("Something broke");
                        }
                    }
                    catch (IndexOutOfRangeException)
                    {
                        res[i] = 0;
                    }
                }
                break;

            case Operation.WriteOutput:
                res = new long[1];

                immediate = WorkingProgram[PC + 1];
                if (modes[0] == Mode.Position)
                {
                    res[0] = WorkingProgram[(int)immediate];
                }
                else if (modes[0] == Mode.Immediate)
                {
                    res[0] = immediate;
                }
                else
                {
                    res[0] = WorkingProgram[(int)immediate + RelativeBase];
                }

                break;

            case Operation.RelativeBaseAdjust:
                res = new long[1];     //Let's just assume that any operation can take 3 params except reading input (must wait for input) and Halting

                immediate = WorkingProgram[PC + 1];
                if (modes[0] == Mode.Position)
                {
                    res[0] = WorkingProgram[(int)immediate];
                }
                else if (modes[0] == Mode.Immediate)
                {
                    res[0] = immediate;
                }
                else
                {
                    res[0] = WorkingProgram[(int)immediate + RelativeBase];
                }

                break;

            case Operation.JumpTrue:
            case Operation.JumpFalse:
                res = new long[2];
                for (int i = 0; i < 2; i++)
                {
                    try
                    {
                        immediate = (int)WorkingProgram[PC + i + 1];
                        if (modes[i] == Mode.Position)
                        {
                            res[i] = WorkingProgram[(int)immediate];
                        }
                        else if (modes[i] == Mode.Immediate)
                        {
                            res[i] = immediate;
                        }
                        else
                        {
                            res[i] = WorkingProgram[(int)immediate + RelativeBase];
                        }
                    }
                    catch (IndexOutOfRangeException)
                    {
                        res[i] = 0;
                    }
                }
                break;

            case Operation.ReadInput:
                res = new long[2];
                int QL = 0;
                do
                {
                    lock (Inputs)
                    {
                        QL = Inputs.Count;
                    }
                } while (QL == 0);


                lock (Inputs)
                {
                    res[0] = Inputs.Dequeue();
                }

                immediate = (int)WorkingProgram[PC + 1];
                if (modes[0] == Mode.Relative)
                {
                    res[1] = (int)immediate + RelativeBase;
                }
                else
                {
                    res[1] = immediate;
                }
                break;


            case Operation.HALT: return(null);

            default:
                throw new Exception("Not a valid Opcode");
            }
            return(res);
        }
Beispiel #4
0
        public void RunIntCode(BreakMode breakMode = BreakMode.Output)
        {
            while (!IsHalted)
            {
                ExecutedInstructions++;
                var instruction = _intCode[_instructionPointer].ToString().PadLeft(5, '0');
                var opCode      = (OpCode)(GetNumber(instruction[3]) * 10 + GetNumber(instruction[4]));
                var modeParam1  = (Mode)GetNumber(instruction[2]);
                var modeParam2  = (Mode)GetNumber(instruction[1]);
                var modeParam3  = (Mode)GetNumber(instruction[0]);

                switch (opCode)
                {
                case OpCode.Sum:
                {
                    var param1Value = GetParamValue(modeParam1, _instructionPointer + 1);
                    var param2Value = GetParamValue(modeParam2, _instructionPointer + 2);
                    var value       = param1Value + param2Value;
                    WriteMem(modeParam3, _instructionPointer + 3, value);
                    _instructionPointer += 4;
                    break;
                }

                case OpCode.Multiply:
                {
                    var param1Value = GetParamValue(modeParam1, _instructionPointer + 1);
                    var param2Value = GetParamValue(modeParam2, _instructionPointer + 2);
                    var value       = param1Value * param2Value;
                    WriteMem(modeParam3, _instructionPointer + 3, value);
                    _instructionPointer += 4;
                    break;
                }

                case OpCode.Input:
                {
                    if (breakMode == BreakMode.Input && Inputs.Count == 0)
                    {
                        return;
                    }

                    WriteMem(modeParam1, _instructionPointer + 1, Inputs.Dequeue());
                    _instructionPointer += 2;
                    break;
                }

                case OpCode.Output:
                {
                    var param2Value = GetParamValue(modeParam1, _instructionPointer + 1);
                    Output.Enqueue(param2Value);
                    _instructionPointer += 2;

                    if (breakMode == BreakMode.Output)
                    {
                        return;
                    }
                    break;
                }

                case OpCode.JumpIfTrue:
                {
                    var param1Value = GetParamValue(modeParam1, _instructionPointer + 1);
                    var param2Value = GetParamValue(modeParam2, _instructionPointer + 2);
                    _instructionPointer = param1Value != 0 ? param2Value : _instructionPointer + 3;
                    break;
                }

                case OpCode.JumpIfFalse:
                {
                    var param1Value = GetParamValue(modeParam1, _instructionPointer + 1);
                    var param2Value = GetParamValue(modeParam2, _instructionPointer + 2);
                    _instructionPointer = param1Value == 0 ? param2Value : _instructionPointer + 3;
                    break;
                }

                case OpCode.LessThan:
                {
                    var param1Value = GetParamValue(modeParam1, _instructionPointer + 1);
                    var param2Value = GetParamValue(modeParam2, _instructionPointer + 2);
                    WriteMem(modeParam3, _instructionPointer + 3, param1Value < param2Value ? 1 : 0);
                    _instructionPointer += 4;
                    break;
                }

                case OpCode.Equals:
                {
                    var param1Value = GetParamValue(modeParam1, _instructionPointer + 1);
                    var param2Value = GetParamValue(modeParam2, _instructionPointer + 2);
                    WriteMem(modeParam3, _instructionPointer + 3, param1Value == param2Value ? 1 : 0);
                    _instructionPointer += 4;
                    break;
                }

                case OpCode.RelativeBaseOffset:
                {
                    var param1Value = GetParamValue(modeParam1, _instructionPointer + 1);
                    _relativeBase       += param1Value;
                    _instructionPointer += 2;
                    break;
                }

                case OpCode.Halt:
                    IsHalted = true;
                    break;

                default:
                    throw new ArgumentOutOfRangeException($"!Unknown OpCode {opCode}!");
                }
            }
        }
Beispiel #5
0
        public void ProcessOpCodes(int[] opCodes)
        {
            for (var i = 0; i < opCodes.Length; i++)
            {
                var op = opCodes[i];

                if (op == 99)
                {
                    break;
                }

                var modeP1 = 0;
                var modeP2 = 0;
                var modeP3 = 0;

                if (op > 99)
                {
                    var ops = op.ToString().PadLeft(5, '0');

                    modeP3 = int.Parse(ops.Substring(0, 1));
                    modeP2 = int.Parse(ops.Substring(1, 1));
                    modeP1 = int.Parse(ops.Substring(2, 1));

                    var newOp = ops.Substring(3);

                    // update the opcode
                    op = int.Parse(newOp);
                }

                if (op == 1)
                {
                    var source1 = opCodes[++i];
                    var source2 = opCodes[++i];
                    var target  = opCodes[++i];

                    var val1 = (modeP1 == 1) ? source1 : opCodes[source1];
                    var val2 = (modeP2 == 1) ? source2 : opCodes[source2];

                    opCodes[target] = val1 + val2;
                }
                else if (op == 2)
                {
                    var source1 = opCodes[++i];
                    var source2 = opCodes[++i];
                    var target  = opCodes[++i];

                    var val1 = (modeP1 == 1) ? source1 : opCodes[source1];
                    var val2 = (modeP2 == 1) ? source2 : opCodes[source2];

                    opCodes[target] = val1 * val2;
                }
                else if (op == 3)
                {
                    var target = opCodes[++i];
                    opCodes[target] = Inputs.Dequeue();
                }
                else if (op == 4)
                {
                    var target = opCodes[++i];

                    var val1 = (modeP1 == 1) ? target : opCodes[target];
                    Output = val1;
                }
                else if (op == 5)
                {
                    // jump if true
                    var source1 = opCodes[++i];
                    var source2 = opCodes[++i];

                    var val1 = (modeP1 == 1) ? source1 : opCodes[source1];
                    var val2 = (modeP2 == 1) ? source2 : opCodes[source2];

                    if (val1 > 0)
                    {
                        i = val2 - 1; // +1 gets added on loop.
                        continue;
                    }
                }
                else if (op == 6)
                {
                    // jump if false
                    var source1 = opCodes[++i];
                    var source2 = opCodes[++i];

                    var val1 = (modeP1 == 1) ? source1 : opCodes[source1];
                    var val2 = (modeP2 == 1) ? source2 : opCodes[source2];

                    if (val1 == 0)
                    {
                        i = val2 - 1; // +1 gets added on loop
                        continue;
                    }
                }
                else if (op == 7)
                {
                    // less than
                    var source1 = opCodes[++i];
                    var source2 = opCodes[++i];
                    var target  = opCodes[++i];

                    var val1 = (modeP1 == 1) ? source1 : opCodes[source1];
                    var val2 = (modeP2 == 1) ? source2 : opCodes[source2];

                    opCodes[target] = (val1 < val2) ? 1 : 0;
                }
                else if (op == 8)
                {
                    // equals
                    var source1 = opCodes[++i];
                    var source2 = opCodes[++i];
                    var target  = opCodes[++i];

                    var val1 = (modeP1 == 1) ? source1 : opCodes[source1];
                    var val2 = (modeP2 == 1) ? source2 : opCodes[source2];

                    opCodes[target] = (val1 == val2) ? 1 : 0;
                }
                else
                {
                    throw new Exception("invalid op");
                }
            }
        }
Beispiel #6
0
 private int GetInput() => Inputs.Dequeue();
Beispiel #7
0
 private int ReadInput()
 {
     return(Inputs.Dequeue());
 }
Beispiel #8
0
            public ExitCode Run()
            {
                try
                {
                    int opcode = 0;

                    while (opcode != 99)
                    {
                        opcode = (int)(Instructions[PC]) % 100;
                        int p1mode = (int)((Instructions[PC] / 100) % 10);
                        int p2mode = (int)((Instructions[PC] / 1000) % 10);
                        int p3mode = (int)((Instructions[PC] / 10000) % 10);

                        BigInteger GetValue(int m, BigInteger v, int mode = 0)
                        {
                            BigInteger a = 0;

                            if (mode == 0)
                            {
                                switch (m)
                                {
                                case 0:
                                    a = Instructions[(int)v];
                                    break;

                                case 1:
                                    a = v;
                                    break;

                                case 2:
                                    a = Instructions[(int)v + RelativeBase];
                                    break;
                                }
                            }
                            else
                            {
                                switch (m)
                                {
                                case 0:
                                    a = v;
                                    break;

                                case 1:
                                    a = v;
                                    break;

                                case 2:
                                    a = (int)v + RelativeBase;
                                    break;
                                }
                            }
                            return(a);
                        }

                        switch (opcode)
                        {
                        case 1:
                            Instructions[(int)GetValue(p3mode, Instructions[PC + 3], 1)] = GetValue(p1mode, Instructions[PC + 1]) + GetValue(p2mode, Instructions[PC + 2]);
                            PC += 4;
                            break;

                        case 2:
                            Instructions[(int)GetValue(p3mode, Instructions[PC + 3], 1)] = GetValue(p1mode, Instructions[PC + 1]) * GetValue(p2mode, Instructions[PC + 2]);
                            PC += 4;
                            break;

                        case 3:
                            if (Inputs.Any())
                            {
                                Instructions[(int)GetValue(p1mode, Instructions[PC + 1], 1)] = Inputs.Dequeue();
                                PC += 2;
                            }
                            else
                            {
                                return(ExitCode.NEED_INPUT);
                            }
                            break;

                        case 4:
                            Outputs.Enqueue(GetValue(p1mode, Instructions[PC + 1]));
                            PC += 2;
                            break;

                        case 5:
                            PC = (int)(GetValue(p1mode, Instructions[PC + 1]) != 0 ? GetValue(p2mode, Instructions[PC + 2]) : (PC + 3));
                            break;

                        case 6:
                            PC = (int)(GetValue(p1mode, Instructions[PC + 1]) == 0 ? GetValue(p2mode, Instructions[PC + 2]) : (PC + 3));
                            break;

                        case 7:
                            Instructions[(int)GetValue(p3mode, Instructions[PC + 3], 1)] = GetValue(p1mode, Instructions[PC + 1]) < GetValue(p2mode, Instructions[PC + 2]) ? 1 : 0;
                            PC += 4;
                            break;

                        case 8:
                            Instructions[(int)GetValue(p3mode, Instructions[PC + 3], 1)] = GetValue(p1mode, Instructions[PC + 1]) == GetValue(p2mode, Instructions[PC + 2]) ? 1 : 0;
                            PC += 4;
                            break;

                        case 9:
                            RelativeBase += (int)GetValue(p1mode, Instructions[PC + 1]);
                            PC           += 2;
                            break;

                        case 99:
                            break;
                        }
                    }
                }
                catch (Exception)
                {
                    Console.WriteLine("Invalid Program");
                    return(ExitCode.EXCEPTION);
                }

                return(ExitCode.HALT);
            }
Beispiel #9
0
            public ExitCode Run()
            {
                try
                {
                    int opcode = 0;

                    while (opcode != 99)
                    {
                        opcode = Instructions[PC] % 100;
                        var p1mode = (Instructions[PC] / 100) % 10;
                        var p2mode = (Instructions[PC] / 1000) % 10;
                        var p3mode = (Instructions[PC] / 10000) % 10;

                        int GetValue(int m, int v) => m != 0 ? v : Instructions[v];

                        switch (opcode)
                        {
                        case 1:
                            Instructions[Instructions[PC + 3]] = GetValue(p1mode, Instructions[PC + 1]) + GetValue(p2mode, Instructions[PC + 2]);
                            PC += 4;
                            break;

                        case 2:
                            Instructions[Instructions[PC + 3]] = GetValue(p1mode, Instructions[PC + 1]) * GetValue(p2mode, Instructions[PC + 2]);
                            PC += 4;
                            break;

                        case 3:
                            if (Inputs.Count() > 0)
                            {
                                Instructions[Instructions[PC + 1]] = Inputs.Dequeue();
                                PC += 2;
                            }
                            else
                            {
                                return(ExitCode.NEED_INPUT);
                            }
                            break;

                        case 4:
                            Outputs.Enqueue(GetValue(p1mode, Instructions[PC + 1]));
                            //Console.WriteLine($"Enqueued {Outputs.Peek()}");
                            PC += 2;
                            break;

                        case 5:
                            PC = GetValue(p1mode, Instructions[PC + 1]) != 0 ? GetValue(p2mode, Instructions[PC + 2]) : (PC + 3);
                            break;

                        case 6:
                            PC = GetValue(p1mode, Instructions[PC + 1]) == 0 ? GetValue(p2mode, Instructions[PC + 2]) : (PC + 3);
                            break;

                        case 7:
                            Instructions[Instructions[PC + 3]] = GetValue(p1mode, Instructions[PC + 1]) < GetValue(p2mode, Instructions[PC + 2]) ? 1 : 0;
                            PC += 4;
                            break;

                        case 8:
                            Instructions[Instructions[PC + 3]] = GetValue(p1mode, Instructions[PC + 1]) == GetValue(p2mode, Instructions[PC + 2]) ? 1 : 0;
                            PC += 4;
                            break;

                        case 99:
                            break;
                        }
                    }
                }
                catch (Exception)
                {
                    Console.WriteLine("Invalid Program");
                    return(ExitCode.EXCEPTION);
                }

                return(ExitCode.HALT);
            }