Beispiel #1
0
        public ICCOutput IntCodeComputer()
        {
            //InitMemory();
            int jumpIndex = 0;

            inputCallBacks = 0;
            ICCOutput iccMainOutput = new ICCOutput();

            while (jumpIndex <= opCodeSequence.Length)
            {
                ICCOutput temp = new ICCOutput();
                temp = ProcessOptCode(ref opCodeSequence, ref jumpIndex);
                //iccMainOutput.opCodeDetected = temp.opCodeDetected;
                if (temp.opCodeDetected == OpCodes.output)
                {
                    iccMainOutput.outputFromPhase = temp.outputFromPhase;
                    //break;
                }
                else if (temp.opCodeDetected == OpCodes.halt || temp.opCodeDetected == OpCodes.unexpectedHalt)
                {
                    Debug.WriteLine(temp.outputFromPhase);
                    iccMainOutput.opCodeDetected = OpCodes.halt;
                    break;
                }
            }
            return(iccMainOutput);
        }
Beispiel #2
0
        public ICCOutput ProcessOptCode(ref int[] opCodeSeq, ref int instructionStart)
        {
            try
            {
                ICCOutput outputStruct = new ICCOutput();
                //new route is ABCDE
                //before we do the operation. We must work out what mode we are in.

                int pos1, pos2, pos3;
                int sequenceSize = opCodeSeq.Length - 1;
                pos3 = (instructionStart + 3) <= sequenceSize ? opCodeSeq[instructionStart + 3] : 0;
                pos2 = instructionStart + 2 <= sequenceSize ? opCodeSeq[instructionStart + 2] : 0;
                pos1 = instructionStart + 1 <= sequenceSize ? opCodeSeq[instructionStart + 1] : 0;
                var opCodeAndParamModeList = ProcessInstruction(opCodeSeq[instructionStart]);
                int val1, val2, val3;

                switch (opCodeAndParamModeList.Item1)
                {
                case OpCodes.add:
                    val1 = RetrieveValueBasedOnMode(opCodeAndParamModeList.Item2[0], opCodeSeq, pos1);
                    val2 = RetrieveValueBasedOnMode(opCodeAndParamModeList.Item2[1], opCodeSeq, pos2);
                    val3 = RetrieveValueBasedOnMode(opCodeAndParamModeList.Item2[2], opCodeSeq, pos3);
                    //moves by 4 params.
                    //Work out what the mode is, then perform the operation.
                    opCodeSeq[pos3]             = RetrieveValueBasedOnMode(opCodeAndParamModeList.Item2[0], opCodeSeq, pos1) + RetrieveValueBasedOnMode(opCodeAndParamModeList.Item2[1], opCodeSeq, pos2);
                    instructionStart           += 4;
                    outputStruct.opCodeDetected = OpCodes.add;
                    break;

                case OpCodes.times:
                    val1 = RetrieveValueBasedOnMode(opCodeAndParamModeList.Item2[0], opCodeSeq, pos1);
                    val2 = RetrieveValueBasedOnMode(opCodeAndParamModeList.Item2[1], opCodeSeq, pos2);
                    val3 = RetrieveValueBasedOnMode(opCodeAndParamModeList.Item2[2], opCodeSeq, pos3);
                    //moves by 4 params
                    opCodeSeq[pos3]             = RetrieveValueBasedOnMode(opCodeAndParamModeList.Item2[0], opCodeSeq, pos1) * RetrieveValueBasedOnMode(opCodeAndParamModeList.Item2[1], opCodeSeq, pos2);
                    instructionStart           += 4;
                    outputStruct.opCodeDetected = OpCodes.times;
                    break;

                case OpCodes.input:
                    if (manualInputs.Count > 0)
                    {
                        opCodeSeq[pos1]   = manualInputs.Dequeue();
                        instructionStart += 2;
                    }
                    break;

                case OpCodes.output:
                    val1                         = RetrieveValueBasedOnMode(opCodeAndParamModeList.Item2[0], opCodeSeq, pos1);
                    instructionStart            += 2;
                    outputStruct.opCodeDetected  = OpCodes.output;
                    outputStruct.outputFromPhase = val1;
                    break;

                case OpCodes.jumpIfTrue:
                    //Opcode 5 is jump-if-true: if the first parameter is non-zero,
                    //it sets the instruction pointer to the value from the second parameter. Otherwise, it does nothing.
                    val1 = RetrieveValueBasedOnMode(opCodeAndParamModeList.Item2[0], opCodeSeq, pos1);
                    if (Math.Abs(val1) > 0)
                    {
                        val2             = RetrieveValueBasedOnMode(opCodeAndParamModeList.Item2[1], opCodeSeq, pos2);
                        instructionStart = val2;
                    }
                    else
                    {
                        instructionStart += 3;
                    }
                    outputStruct.opCodeDetected = OpCodes.jumpIfTrue;
                    break;

                case OpCodes.jumpIfFalse:
                    //Opcode 6 is jump-if-false: if the first parameter is zero,
                    //it sets the instruction pointer to the value from the second parameter. Otherwise, it does nothing.
                    val1 = RetrieveValueBasedOnMode(opCodeAndParamModeList.Item2[0], opCodeSeq, pos1);
                    if (val1 == 0)
                    {
                        val2             = RetrieveValueBasedOnMode(opCodeAndParamModeList.Item2[1], opCodeSeq, pos2);
                        instructionStart = val2;
                    }
                    else
                    {
                        instructionStart += 3;
                    }
                    outputStruct.opCodeDetected = OpCodes.jumpIfFalse;
                    break;

                case OpCodes.isLessThan:
                    //Opcode 7 is less than: if the first parameter is less than the second parameter,
                    //it stores 1 in the position given by the third parameter. Otherwise, it stores 0.
                    val1                        = RetrieveValueBasedOnMode(opCodeAndParamModeList.Item2[0], opCodeSeq, pos1);
                    val2                        = RetrieveValueBasedOnMode(opCodeAndParamModeList.Item2[1], opCodeSeq, pos2);
                    val3                        = RetrieveValueBasedOnMode(opCodeAndParamModeList.Item2[2], opCodeSeq, pos3);
                    opCodeSeq[pos3]             = val1 < val2 ? 1 : 0;
                    instructionStart           += 4;
                    outputStruct.opCodeDetected = OpCodes.isLessThan;
                    break;

                case OpCodes.isEquals:
                    //Opcode 8 is equals: if the first parameter is equal to the second parameter,
                    //it stores 1 in the position given by the third parameter. Otherwise, it stores 0.
                    val1                        = RetrieveValueBasedOnMode(opCodeAndParamModeList.Item2[0], opCodeSeq, pos1);
                    val2                        = RetrieveValueBasedOnMode(opCodeAndParamModeList.Item2[1], opCodeSeq, pos2);
                    val3                        = RetrieveValueBasedOnMode(opCodeAndParamModeList.Item2[2], opCodeSeq, pos3);
                    opCodeSeq[pos3]             = val1 == val2 ? 1 : 0;
                    instructionStart           += 4;
                    outputStruct.opCodeDetected = OpCodes.isEquals;
                    break;

                case OpCodes.halt:
                    outputStruct.opCodeDetected = OpCodes.halt;
                    break;
                }
                return(outputStruct);
            }
            catch (Exception exc)
            {
                Debug.WriteLine(exc.Message);
                ICCOutput oc = new ICCOutput();
                oc.opCodeDetected = OpCodes.unexpectedHalt;
                return(oc);
            }
        }