Пример #1
0
            public void Run()
            {
                while (_iPointer >= 0 && _iPointer < Memory.Length)
                {
                    var instruction = Memory[_iPointer];
                    var opCode      = instruction % 100;

                    switch (opCode)
                    {
                    case 1: Add(); break;

                    case 2: Multiply(); break;

                    case 3: if (!InputQueue.Any())
                        {
                            return;
                        }
                        ReadInput(); break;

                    case 4: WriteOutput(); break;

                    case 5: JumpIfTrue(); break;

                    case 6: JumpIfFalse(); break;

                    case 7: LessThan(); break;

                    case 8: Equals(); break;

                    case 99: Halted = true; return;

                    default: throw new Exception($"Unexpected opcode: {opCode}");
                    }
                }
            }
Пример #2
0
 public bool AwaitingInput()
 {
     return(PeekNext() == 3 && !InputQueue.Any());
 }
Пример #3
0
        public long RunNext()
        {
            string fullOpcode = Memory[InstructionPtr].ToString().PadLeft(5, '0');
            long   opcode     = long.Parse(fullOpcode.Substring(3, 2));
            long   param1Mode = long.Parse(fullOpcode.Substring(2, 1));
            long   param2Mode = long.Parse(fullOpcode.Substring(1, 1));
            long   param3Mode = long.Parse(fullOpcode.Substring(0, 1));

            long param1 = 0;
            long param2 = 0;
            long param3 = 0;

            long param1Key = 0;
            long param2Key = 0;
            long param3Key = 0;

            if (new long[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }.Contains(opcode))
            {
                if (!Memory.ContainsKey(InstructionPtr + 1))
                {
                    Memory.Add(InstructionPtr + 1, 0);
                }
                switch (param1Mode)
                {
                case 0:
                    param1Key = Memory[InstructionPtr + 1];
                    if (!Memory.ContainsKey(param1Key))
                    {
                        Memory.Add(param1Key, 0);
                    }
                    param1 = Memory[param1Key];
                    break;

                case 1:
                    param1 = Memory[InstructionPtr + 1];
                    break;

                case 2:
                    param1Key = RelativeBase + Memory[InstructionPtr + 1];
                    if (!Memory.ContainsKey(param1Key))
                    {
                        Memory.Add(param1Key, 0);
                    }
                    param1 = Memory[param1Key];
                    break;
                }
            }

            if (new long[] { 1, 2, 5, 6, 7, 8 }.Contains(opcode))
            {
                if (!Memory.ContainsKey(InstructionPtr + 2))
                {
                    Memory.Add(InstructionPtr + 2, 0);
                }
                switch (param2Mode)
                {
                case 0:
                    param2Key = Memory[InstructionPtr + 2];
                    if (!Memory.ContainsKey(param2Key))
                    {
                        Memory.Add(param2Key, 0);
                    }
                    param2 = Memory[param2Key];
                    break;

                case 1:
                    param2 = Memory[InstructionPtr + 2];
                    break;

                case 2:
                    param2Key = RelativeBase + Memory[InstructionPtr + 2];
                    if (!Memory.ContainsKey(param2Key))
                    {
                        Memory.Add(param2Key, 0);
                    }
                    param2 = Memory[param2Key];
                    break;
                }
            }

            if (new long[] { 1, 2, 7, 8 }.Contains(opcode))
            {
                if (!Memory.ContainsKey(InstructionPtr + 3))
                {
                    Memory.Add(InstructionPtr + 3, 0);
                }
                switch (param3Mode)
                {
                case 0:
                    param3Key = Memory[InstructionPtr + 3];
                    if (!Memory.ContainsKey(param3Key))
                    {
                        Memory.Add(param3Key, 0);
                    }
                    param3 = Memory[param3Key];
                    break;

                case 1:
                    param3 = Memory[InstructionPtr + 3];
                    break;

                case 2:
                    param3Key = RelativeBase + Memory[InstructionPtr + 3];
                    if (!Memory.ContainsKey(param3Key))
                    {
                        Memory.Add(param3Key, 0);
                    }
                    param3 = Memory[param3Key];
                    break;
                }
            }

            switch (opcode)
            {
            case 1:
                Memory[param3Key] = param1 + param2;
                InstructionPtr   += 4;
                break;

            case 2:
                Memory[param3Key] = param1 * param2;
                InstructionPtr   += 4;
                break;

            case 3:
                bool success = false;
                long parsed  = long.MinValue;
                while (!success)
                {
                    string input;
                    if (InputQueue.Any())
                    {
                        input = InputQueue.Dequeue().ToString();
                        if (PrintOutput)
                        {
                            Console.WriteLine($"Input: {input}");
                        }
                    }
                    else if (AsciiInputMode)
                    {
                        string line = Console.ReadLine();
                        AddAsciiInput(line + "\n");
                        input = "";
                    }
                    else
                    {
                        Console.Write("Input: ");
                        input = Console.ReadLine();
                    }
                    success = long.TryParse(input.Trim(), out parsed);
                }
                Memory[param1Key] = parsed;
                InstructionPtr   += 2;
                break;

            case 4:
                if (PrintOutput)
                {
                    Console.WriteLine($"Output: {param1}");
                }
                OutputQueue.Enqueue(param1);
                InstructionPtr += 2;
                break;

            case 5:
                if (param1 != 0)
                {
                    InstructionPtr = param2;
                }
                else
                {
                    InstructionPtr += 3;
                }
                break;

            case 6:
                if (param1 == 0)
                {
                    InstructionPtr = param2;
                }
                else
                {
                    InstructionPtr += 3;
                }
                break;

            case 7:
                Memory[param3Key] = param1 < param2 ? 1 : 0;
                InstructionPtr   += 4;
                break;

            case 8:
                Memory[param3Key] = param1 == param2 ? 1 : 0;
                InstructionPtr   += 4;
                break;

            case 9:
                RelativeBase   += param1;
                InstructionPtr += 2;
                break;

            case 99:
                return(Memory[0]);

            default:
                throw new Exception($"Unknown opcode: {opcode} at {InstructionPtr}");
            }

            return(long.MinValue);
        }
Пример #4
0
        //public Queue<long> Compute()
        public void Compute()
        {
            long pc = 0;    //program counter
            long rb = 0;    //relative base

            while (pc < memory.Length)
            {
                var  instruction = memory[pc].ToString("00000");
                long opcode      = int.Parse(instruction.Substring(instruction.Length - 2));
                char p1Mode      = instruction[2];
                char p2Mode      = instruction[1];
                char p3Mode      = instruction[0];

                if (opcode == 99)
                {
                    //halt
                    break;
                }
                else if (opcode == 1)
                {
                    //add
                    SetParameter(pc + 3, p3Mode, rb, GetParameter(pc + 1, p1Mode, rb) + GetParameter(pc + 2, p2Mode, rb));
                    pc += 4;
                }
                else if (opcode == 2)
                {
                    //mult
                    SetParameter(pc + 3, p3Mode, rb, GetParameter(pc + 1, p1Mode, rb) * GetParameter(pc + 2, p2Mode, rb));
                    pc += 4;
                }
                else if (opcode == 3)
                {
                    //read input from inputQueue
                    bool spinlock = true;
                    while (spinlock)
                    {
                        lock (InputQueue){
                            if (InputQueue.Any())
                            {
                                SetParameter(pc + 1, p1Mode, rb, InputQueue.Dequeue());
                                spinlock = false;
                            }
                        }
                    }
                    pc += 2;
                }
                else if (opcode == 4)
                {
                    //write output
                    var output = GetParameter(pc + 1, p1Mode, rb);
                    if (OutputToConsole)
                    {
                        Console.WriteLine(output);
                    }
                    lock (OutputQueue)
                    {
                        OutputQueue.Enqueue(output);
                    }
                    pc += 2;
                }
                else if (opcode == 5)
                {
                    //jump if true
                    if (GetParameter(pc + 1, p1Mode, rb) != 0)
                    {
                        pc = GetParameter(pc + 2, p2Mode, rb);
                    }
                    else
                    {
                        pc += 3;
                    }
                }
                else if (opcode == 6)
                {
                    //jump if false
                    if (GetParameter(pc + 1, p1Mode, rb) == 0)
                    {
                        pc = GetParameter(pc + 2, p2Mode, rb);
                    }
                    else
                    {
                        pc += 3;
                    }
                }
                else if (opcode == 7)
                {
                    //less than
                    if (GetParameter(pc + 1, p1Mode, rb) < GetParameter(pc + 2, p2Mode, rb))
                    {
                        SetParameter(pc + 3, p3Mode, rb, 1);
                    }
                    else
                    {
                        SetParameter(pc + 3, p3Mode, rb, 0);
                    }
                    pc += 4;
                }
                else if (opcode == 8)
                {
                    //equals
                    if (GetParameter(pc + 1, p1Mode, rb) == GetParameter(pc + 2, p2Mode, rb))
                    {
                        SetParameter(pc + 3, p3Mode, rb, 1);
                    }
                    else
                    {
                        SetParameter(pc + 3, p3Mode, rb, 0);
                    }
                    pc += 4;
                }
                else if (opcode == 9)
                {
                    rb += GetParameter(pc + 1, p1Mode, rb);
                    pc += 2;
                }
                else
                {
                    Console.WriteLine("ERR!!!!!");
                }
            }
            //return OutputQueue;
        }