Advertisement
Guest User

Untitled

a guest
Dec 5th, 2019
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.58 KB | None | 0 0
  1.     public class OpcodeParser
  2.     {
  3.         private const int OPCODE_ADD = 1;
  4.         private const int OPCODE_MULTIPLY = 2;
  5.         private const int OPCODE_INPUT = 3;
  6.         private const int OPCODE_OUTPUT = 4;
  7.         private const int OPCODE_JUMP_IF_TRUE = 5;
  8.         private const int OPCODE_JUMP_IF_FALSE = 6;
  9.         private const int OPCODE_LESS_THAN = 7;
  10.         private const int OPCODE_EQUALS = 8;
  11.         private const int OPCODE_HALT = 99;
  12.  
  13.         private int[] _memory;
  14.         private int[] _originalMemory;
  15.         private int _pointer = 0;
  16.         private bool _halted = false;
  17.         private Queue<int> _inputQueue = new Queue<int>();
  18.         private Queue<int> _outputQueue = new Queue<int>();
  19.  
  20.         public OpcodeParser(string[] splitInput)
  21.         {
  22.             _memory = new int[splitInput.Length];
  23.             _originalMemory = new int[splitInput.Length];
  24.             int cur;
  25.             for (int i = 0; i < splitInput.Length; i++)
  26.             {
  27.                 cur = int.Parse(splitInput[i]);
  28.                 _memory[i] = cur;
  29.                 _originalMemory[i] = cur;
  30.             }
  31.         }
  32.  
  33.         public void ResetMemory()
  34.         {
  35.             for (int i = 0; i < _memory.Length; i++)
  36.             {
  37.                 _memory[i] = _originalMemory[i];
  38.             }
  39.             _pointer = 0;
  40.             _halted = false;
  41.             _inputQueue = new Queue<int>();
  42.             _outputQueue = new Queue<int>();
  43.         }
  44.  
  45.         public int GetValue(int address)
  46.         {
  47.             return _memory[address];
  48.         }
  49.  
  50.         public void SetValue(int address, int value)
  51.         {
  52.             _memory[address] = value;
  53.         }
  54.  
  55.         public void ParseToEnd()
  56.         {
  57.             while (_pointer < _memory.Length && !_halted)
  58.             {
  59.                 Step();
  60.             }
  61.         }
  62.  
  63.         public void Step()
  64.         {
  65.             if (_halted) return;
  66.  
  67.             int full = _memory[_pointer];
  68.             char[] digits = full.ToString().ToCharArray();
  69.             int[] corrected = new int[5];
  70.             for (int diff = 0; diff < digits.Length; diff++)
  71.             {
  72.                 corrected[corrected.Length - 1 - diff] = (int)char.GetNumericValue(digits[digits.Length - 1 - diff]);
  73.             }
  74.  
  75.             bool immediateParameter3 = corrected[0] == 1;
  76.             bool immediateParameter2 = corrected[1] == 1;
  77.             bool immediateParameter1 = corrected[2] == 1;
  78.             int opcode = (10 * corrected[3]) + corrected[4];
  79.             switch (opcode)
  80.             {
  81.                 case OPCODE_HALT:
  82.                     _halted = true;
  83.                     return;
  84.                 case OPCODE_ADD:
  85.                     DoAdd(immediateParameter1, immediateParameter2);
  86.                     break;
  87.                 case OPCODE_MULTIPLY:
  88.                     DoMultiply(immediateParameter1, immediateParameter2);
  89.                     break;
  90.                 case OPCODE_INPUT:
  91.                     DoInput();
  92.                     break;
  93.                 case OPCODE_OUTPUT:
  94.                     DoOutput(immediateParameter1);
  95.                     break;
  96.                 case OPCODE_JUMP_IF_TRUE:
  97.                     DoJumpIfTrue(immediateParameter1, immediateParameter2);
  98.                     break;
  99.                 case OPCODE_JUMP_IF_FALSE:
  100.                     DoJumpIfFalse(immediateParameter1, immediateParameter2);
  101.                     break;
  102.                 case OPCODE_LESS_THAN:
  103.                     DoLessThan(immediateParameter1, immediateParameter2);
  104.                     break;
  105.                 case OPCODE_EQUALS:
  106.                     DoEquals(immediateParameter1, immediateParameter2);
  107.                     break;
  108.             }
  109.         }
  110.  
  111.         public void AddInputs(params int[] inputs)
  112.         {
  113.             foreach (int input in inputs)
  114.             {
  115.                 this._inputQueue.Enqueue(input);
  116.             }
  117.         }
  118.  
  119.         private void DoAdd(bool immediateParam1, bool immediateParam2)
  120.         {
  121.             int inputA = _memory[_pointer + 1];
  122.             int inputB = _memory[_pointer + 2];
  123.             int valueA = immediateParam1 ? inputA : _memory[inputA];
  124.             int valueB = immediateParam2 ? inputB : _memory[inputB];
  125.             int outputAddress = _memory[_pointer + 3];
  126.             _memory[outputAddress] = valueA + valueB;
  127.             _pointer += 4;
  128.         }
  129.  
  130.         private void DoMultiply(bool immediateParam1, bool immediateParam2)
  131.         {
  132.             int inputA = _memory[_pointer + 1];
  133.             int inputB = _memory[_pointer + 2];
  134.             int valueA = immediateParam1 ? inputA : _memory[inputA];
  135.             int valueB = immediateParam2 ? inputB : _memory[inputB];
  136.             int outputAddress = _memory[_pointer + 3];
  137.             _memory[outputAddress] = valueA * valueB;
  138.             _pointer += 4;
  139.         }
  140.  
  141.         private void DoInput()
  142.         {
  143.             var input = ReadFromInputQueue();
  144.             int outputAddress = _memory[_pointer + 1];
  145.             _memory[outputAddress] = input;
  146.             _pointer += 2;
  147.         }
  148.  
  149.         private void DoOutput(bool immediateParam1)
  150.         {
  151.             int output = _memory[_pointer + 1];
  152.             int value = immediateParam1 ? output : _memory[output];
  153.             Console.WriteLine("Output: " + value);
  154.             _outputQueue.Enqueue(value);
  155.             _pointer += 2;
  156.         }
  157.  
  158.         private void DoJumpIfTrue(bool immediateParam1, bool immediateParam2)
  159.         {
  160.             int inputA = _memory[_pointer + 1];
  161.             int inputB = _memory[_pointer + 2];
  162.             int valueA = immediateParam1 ? inputA : _memory[inputA];
  163.             int valueB = immediateParam2 ? inputB : _memory[inputB];
  164.             if (valueA != 0) _pointer = valueB;
  165.             else _pointer += 3;
  166.         }
  167.  
  168.         private void DoJumpIfFalse(bool immediateParam1, bool immediateParam2)
  169.         {
  170.             int inputA = _memory[_pointer + 1];
  171.             int inputB = _memory[_pointer + 2];
  172.             int valueA = immediateParam1 ? inputA : _memory[inputA];
  173.             int valueB = immediateParam2 ? inputB : _memory[inputB];
  174.             if (valueA == 0) _pointer = valueB;
  175.             else _pointer += 3;
  176.         }
  177.  
  178.         private void DoLessThan(bool immediateParam1, bool immediateParam2)
  179.         {
  180.             int inputA = _memory[_pointer + 1];
  181.             int inputB = _memory[_pointer + 2];
  182.             int valueA = immediateParam1 ? inputA : _memory[inputA];
  183.             int valueB = immediateParam2 ? inputB : _memory[inputB];
  184.             int outputAddress = _memory[_pointer + 3];
  185.             _memory[outputAddress] = (valueA < valueB) ? 1 : 0;
  186.             _pointer += 4;
  187.         }
  188.  
  189.         private void DoEquals(bool immediateParam1, bool immediateParam2)
  190.         {
  191.             int inputA = _memory[_pointer + 1];
  192.             int inputB = _memory[_pointer + 2];
  193.             int valueA = immediateParam1 ? inputA : _memory[inputA];
  194.             int valueB = immediateParam2 ? inputB : _memory[inputB];
  195.             int outputAddress = _memory[_pointer + 3];
  196.             _memory[outputAddress] = (valueA == valueB) ? 1 : 0;
  197.             _pointer += 4;
  198.         }
  199.  
  200.         private int ReadFromInputQueue()
  201.         {
  202.             if (_inputQueue.Count == 0) throw new Exception("Tried to get input but none were found");
  203.             return _inputQueue.Dequeue();
  204.         }
  205.  
  206.         public int ReadFromOutputQueue()
  207.         {
  208.             if (_outputQueue.Count == 0) throw new Exception("Tried to read from output but none were found");
  209.             return _outputQueue.Dequeue();
  210.         }
  211.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement