Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class OpcodeParser
- {
- private const int OPCODE_ADD = 1;
- private const int OPCODE_MULTIPLY = 2;
- private const int OPCODE_INPUT = 3;
- private const int OPCODE_OUTPUT = 4;
- private const int OPCODE_JUMP_IF_TRUE = 5;
- private const int OPCODE_JUMP_IF_FALSE = 6;
- private const int OPCODE_LESS_THAN = 7;
- private const int OPCODE_EQUALS = 8;
- private const int OPCODE_HALT = 99;
- private int[] _memory;
- private int[] _originalMemory;
- private int _pointer = 0;
- private bool _halted = false;
- private Queue<int> _inputQueue = new Queue<int>();
- private Queue<int> _outputQueue = new Queue<int>();
- public OpcodeParser(string[] splitInput)
- {
- _memory = new int[splitInput.Length];
- _originalMemory = new int[splitInput.Length];
- int cur;
- for (int i = 0; i < splitInput.Length; i++)
- {
- cur = int.Parse(splitInput[i]);
- _memory[i] = cur;
- _originalMemory[i] = cur;
- }
- }
- public void ResetMemory()
- {
- for (int i = 0; i < _memory.Length; i++)
- {
- _memory[i] = _originalMemory[i];
- }
- _pointer = 0;
- _halted = false;
- _inputQueue = new Queue<int>();
- _outputQueue = new Queue<int>();
- }
- public int GetValue(int address)
- {
- return _memory[address];
- }
- public void SetValue(int address, int value)
- {
- _memory[address] = value;
- }
- public void ParseToEnd()
- {
- while (_pointer < _memory.Length && !_halted)
- {
- Step();
- }
- }
- public void Step()
- {
- if (_halted) return;
- int full = _memory[_pointer];
- char[] digits = full.ToString().ToCharArray();
- int[] corrected = new int[5];
- for (int diff = 0; diff < digits.Length; diff++)
- {
- corrected[corrected.Length - 1 - diff] = (int)char.GetNumericValue(digits[digits.Length - 1 - diff]);
- }
- bool immediateParameter3 = corrected[0] == 1;
- bool immediateParameter2 = corrected[1] == 1;
- bool immediateParameter1 = corrected[2] == 1;
- int opcode = (10 * corrected[3]) + corrected[4];
- switch (opcode)
- {
- case OPCODE_HALT:
- _halted = true;
- return;
- case OPCODE_ADD:
- DoAdd(immediateParameter1, immediateParameter2);
- break;
- case OPCODE_MULTIPLY:
- DoMultiply(immediateParameter1, immediateParameter2);
- break;
- case OPCODE_INPUT:
- DoInput();
- break;
- case OPCODE_OUTPUT:
- DoOutput(immediateParameter1);
- break;
- case OPCODE_JUMP_IF_TRUE:
- DoJumpIfTrue(immediateParameter1, immediateParameter2);
- break;
- case OPCODE_JUMP_IF_FALSE:
- DoJumpIfFalse(immediateParameter1, immediateParameter2);
- break;
- case OPCODE_LESS_THAN:
- DoLessThan(immediateParameter1, immediateParameter2);
- break;
- case OPCODE_EQUALS:
- DoEquals(immediateParameter1, immediateParameter2);
- break;
- }
- }
- public void AddInputs(params int[] inputs)
- {
- foreach (int input in inputs)
- {
- this._inputQueue.Enqueue(input);
- }
- }
- private void DoAdd(bool immediateParam1, bool immediateParam2)
- {
- int inputA = _memory[_pointer + 1];
- int inputB = _memory[_pointer + 2];
- int valueA = immediateParam1 ? inputA : _memory[inputA];
- int valueB = immediateParam2 ? inputB : _memory[inputB];
- int outputAddress = _memory[_pointer + 3];
- _memory[outputAddress] = valueA + valueB;
- _pointer += 4;
- }
- private void DoMultiply(bool immediateParam1, bool immediateParam2)
- {
- int inputA = _memory[_pointer + 1];
- int inputB = _memory[_pointer + 2];
- int valueA = immediateParam1 ? inputA : _memory[inputA];
- int valueB = immediateParam2 ? inputB : _memory[inputB];
- int outputAddress = _memory[_pointer + 3];
- _memory[outputAddress] = valueA * valueB;
- _pointer += 4;
- }
- private void DoInput()
- {
- var input = ReadFromInputQueue();
- int outputAddress = _memory[_pointer + 1];
- _memory[outputAddress] = input;
- _pointer += 2;
- }
- private void DoOutput(bool immediateParam1)
- {
- int output = _memory[_pointer + 1];
- int value = immediateParam1 ? output : _memory[output];
- Console.WriteLine("Output: " + value);
- _outputQueue.Enqueue(value);
- _pointer += 2;
- }
- private void DoJumpIfTrue(bool immediateParam1, bool immediateParam2)
- {
- int inputA = _memory[_pointer + 1];
- int inputB = _memory[_pointer + 2];
- int valueA = immediateParam1 ? inputA : _memory[inputA];
- int valueB = immediateParam2 ? inputB : _memory[inputB];
- if (valueA != 0) _pointer = valueB;
- else _pointer += 3;
- }
- private void DoJumpIfFalse(bool immediateParam1, bool immediateParam2)
- {
- int inputA = _memory[_pointer + 1];
- int inputB = _memory[_pointer + 2];
- int valueA = immediateParam1 ? inputA : _memory[inputA];
- int valueB = immediateParam2 ? inputB : _memory[inputB];
- if (valueA == 0) _pointer = valueB;
- else _pointer += 3;
- }
- private void DoLessThan(bool immediateParam1, bool immediateParam2)
- {
- int inputA = _memory[_pointer + 1];
- int inputB = _memory[_pointer + 2];
- int valueA = immediateParam1 ? inputA : _memory[inputA];
- int valueB = immediateParam2 ? inputB : _memory[inputB];
- int outputAddress = _memory[_pointer + 3];
- _memory[outputAddress] = (valueA < valueB) ? 1 : 0;
- _pointer += 4;
- }
- private void DoEquals(bool immediateParam1, bool immediateParam2)
- {
- int inputA = _memory[_pointer + 1];
- int inputB = _memory[_pointer + 2];
- int valueA = immediateParam1 ? inputA : _memory[inputA];
- int valueB = immediateParam2 ? inputB : _memory[inputB];
- int outputAddress = _memory[_pointer + 3];
- _memory[outputAddress] = (valueA == valueB) ? 1 : 0;
- _pointer += 4;
- }
- private int ReadFromInputQueue()
- {
- if (_inputQueue.Count == 0) throw new Exception("Tried to get input but none were found");
- return _inputQueue.Dequeue();
- }
- public int ReadFromOutputQueue()
- {
- if (_outputQueue.Count == 0) throw new Exception("Tried to read from output but none were found");
- return _outputQueue.Dequeue();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement