Advertisement
Guest User

Untitled

a guest
Dec 21st, 2019
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.32 KB | None | 0 0
  1. class Intcode_computer
  2. {
  3. public:
  4.  
  5.     explicit Intcode_computer(const std::vector<int64_t>& mem)
  6.         :memory{mem}
  7.     {
  8.     }
  9.  
  10.     bool process_next_instruction()
  11.     {
  12.         auto instruction = to_instruction(get_opcode());
  13.         auto parameters = parse_parameters(get_parametercode(), instruction);
  14.         return process_instruction(instruction, parameters);
  15.     }
  16.  
  17.     void set_userinput(int u_i)
  18.     {
  19.         userinput = u_i;
  20.     }
  21.  
  22. private:
  23.  
  24.     enum Instruction
  25.     {
  26.         add = 1,
  27.         mult = 2,
  28.         write_userinput = 3,
  29.         output = 4,
  30.         jump_if_true = 5,
  31.         jump_if_false = 6,
  32.         less_than = 7,
  33.         equals = 8,
  34.         adjust_relative_base = 9,
  35.         exit = 99
  36.     };
  37.  
  38.     enum Parametermode
  39.     {
  40.         position,
  41.         immediate,
  42.         relative
  43.     };
  44.  
  45.     Instruction to_instruction(int opcode)
  46.     {
  47.         return static_cast<Instruction>(opcode);
  48.     }
  49.  
  50.     std::vector<int64_t> parse_parameters(int parametercode, const Instruction& instruction)
  51.     {
  52.         std::vector<int64_t> p;
  53.         switch (instruction)
  54.         {
  55.             // cases where three parameters are used
  56.             case add:
  57.             case mult:
  58.             case less_than:
  59.             case equals:
  60.             {
  61.                 for (int i = 0; i < 3; ++i)
  62.                 {
  63.                     switch (parametercode % 10)
  64.                     {
  65.                         case position:
  66.                         {
  67.                             p.push_back(memory[instruction_ptr + i + 1]);
  68.                             parametercode /= 10;
  69.                             break;
  70.                         }
  71.                         case immediate:
  72.                         {
  73.                             p.push_back(instruction_ptr + i + 1);
  74.                             parametercode /= 10;
  75.                             break;
  76.                         }
  77.                         case relative:
  78.                         {
  79.                             p.push_back(memory[instruction_ptr + i + 1] + relative_base);
  80.                             parametercode /= 10;
  81.                             break;
  82.                         }
  83.                     }
  84.                 }
  85.                 break;
  86.             }
  87.  
  88.             //cases where two parameters are used
  89.             case jump_if_true:
  90.             case jump_if_false:
  91.             {
  92.                 for (int i = 0; i < 2; ++i)
  93.                 {
  94.                     switch (parametercode % 10)
  95.                     {
  96.                         case position:
  97.                         {
  98.                             p.push_back(memory[instruction_ptr + i + 1]);
  99.                             parametercode /= 10;
  100.                             break;
  101.                         }
  102.                         case immediate:
  103.                         {
  104.                             p.push_back(instruction_ptr + i + 1);
  105.                             parametercode /= 10;
  106.                             break;
  107.                         }
  108.                         case relative:
  109.                         {
  110.                             p.push_back(memory[instruction_ptr + i + 1] + relative_base);
  111.                             parametercode /= 10;
  112.                             break;
  113.                         }
  114.                     }
  115.                 }
  116.                 break;
  117.             }
  118.  
  119.             // cases where one parameter is used
  120.             case write_userinput:
  121.             case output:
  122.             case adjust_relative_base:
  123.             {
  124.                 switch (parametercode % 10)
  125.                 {
  126.                     case position:
  127.                     {
  128.                         p.push_back(memory[instruction_ptr + 1]);
  129.                         break;
  130.                     }
  131.                     case immediate:
  132.                     {
  133.                         p.push_back(instruction_ptr + 1);
  134.                         break;
  135.                     }
  136.                     case relative:
  137.                     {
  138.                         p.push_back(memory[instruction_ptr + 1] + relative_base);
  139.                         break;
  140.                     }
  141.                 }
  142.             }
  143.  
  144.             // handle exit
  145.             case exit:
  146.             {
  147.                 break;
  148.             }
  149.             default:
  150.             {
  151.                 std::cout << "error has occured\n";
  152.                 break;
  153.             }
  154.         }
  155.         return p;
  156.     }
  157.  
  158.     // return false if exit instruction is encountered
  159.     bool process_instruction(Instruction instruction, const std::vector<int64_t>& p)
  160.     {
  161.         auto& m = memory;
  162.         switch (instruction)
  163.         {
  164.             case add:
  165.             {
  166.                 m[p[2]] = m[p[1]] + m[p[0]];
  167.                 instruction_ptr += 4;
  168.                 return true;
  169.             }
  170.             case mult:
  171.             {
  172.                 m[p[2]] = m[p[1]] * m[p[0]];
  173.                 instruction_ptr += 4;
  174.                 return true;
  175.             }
  176.             case write_userinput:
  177.             {
  178.                 m[p[0]] = userinput;
  179.                 instruction_ptr += 2;
  180.                 return true;
  181.             }
  182.             case output:
  183.             {
  184.                 std::cout << m[p[0]] << std::endl;
  185.                 instruction_ptr += 2;
  186.                 return true;
  187.             }
  188.             case jump_if_true:
  189.             {
  190.                 if (m[p[0]] != 0)
  191.                 {
  192.                     instruction_ptr = m[p[1]];
  193.                 }
  194.                 else
  195.                 {
  196.                     instruction_ptr += 3;
  197.                 }
  198.                 return true;
  199.             }
  200.             case jump_if_false:
  201.             {
  202.                 if (m[p[0]] == 0)
  203.                 {
  204.                     instruction_ptr = m[p[1]];
  205.                 }
  206.                 else
  207.                 {
  208.                     instruction_ptr += 3;
  209.                 }
  210.                 return true;
  211.             }
  212.             case less_than:
  213.             {
  214.                 if (m[p[0]] < m[p[1]])
  215.                 {
  216.                     m[p[2]] = 1;
  217.                 }
  218.                 else
  219.                 {
  220.                     m[p[2]] = 0;
  221.                 }
  222.                 instruction_ptr += 4;
  223.                 return true;
  224.             }
  225.             case equals:
  226.             {
  227.                 if (m[p[0]] == m[p[1]])
  228.                 {
  229.                     m[p[2]] = 1;
  230.                 }
  231.                 else
  232.                 {
  233.                     m[p[2]] = 0;
  234.                 }
  235.                 instruction_ptr += 4;
  236.                 return true;
  237.             }
  238.             case adjust_relative_base:
  239.             {
  240.                 relative_base += m[p[0]];
  241.                 instruction_ptr += 2;
  242.                 return true;
  243.             }
  244.             case exit:
  245.             {
  246.                 return false;
  247.             }
  248.         }
  249.     }
  250.  
  251.     int get_opcode()
  252.     {
  253.         return memory[instruction_ptr] % 100;
  254.     }
  255.  
  256.     int get_parametercode()
  257.     {
  258.         return memory[instruction_ptr] / 100;
  259.     }
  260.  
  261.     int relative_base = 0;
  262.  
  263.     int userinput = -1;
  264.     int instruction_ptr = 0;
  265.     std::vector<int64_t> memory;
  266. };
  267.  
  268. int main()
  269. {
  270.     auto intcode = read_and_parse_input();
  271.     Intcode_computer machine{intcode};
  272.     machine.set_userinput(2);
  273.  
  274.     while (machine.process_next_instruction());
  275. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement