Advertisement
video_game

AOC2019_Intcode

Dec 6th, 2019
592
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.77 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4.  
  5. namespace Common
  6. {
  7.     public static class Intcode
  8.     {
  9.         public delegate int InputHandler();
  10.         public delegate void OutputHandler(int value);
  11.         public delegate void Logger(string message);
  12.  
  13.         public static int[] Run(string program, InputHandler input = null, OutputHandler output = null, Logger logger = null)
  14.             => Intcode.Run(program.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(str => int.Parse(str)), input, output, logger);
  15.  
  16.         static int resolveParam(int paramIdx, int pctr, int[] memory)
  17.         {
  18.             var instr = memory[pctr];
  19.             var mode = (instr / (int)Math.Pow(10, paramIdx + 2)) % 10;
  20.  
  21.             switch (mode)
  22.             {
  23.                 case 0: return memory[memory[pctr + 1 + paramIdx]];         // Position mode
  24.                 case 1: return memory[pctr + 1 + paramIdx];                 // Immediate mode
  25.                 default: throw new Exception($"Unknown mode {mode}");
  26.             }
  27.         }
  28.  
  29.         public static int[] Run(IEnumerable<int> program, InputHandler input = null, OutputHandler output = null, Logger logger = null)
  30.         {
  31.             if (input == null) input = () => int.Parse(Console.ReadLine());
  32.             if (output == null) output = (val) => Console.WriteLine(val);
  33.  
  34.             var memory = program.ToArray();
  35.  
  36.             var pctr = 0;
  37.             bool running = true;
  38.  
  39.             while (running)
  40.             {
  41.                 var instr = memory[pctr];
  42.  
  43.                 void log(string message) => logger?.Invoke($"{instr}: {message}");
  44.  
  45.                 switch (instr % 100)
  46.                 {
  47.                     case 1:
  48.                     {
  49.                         var x1 = resolveParam(0, pctr, memory);
  50.                         var x2 = resolveParam(1, pctr, memory);
  51.                         var pout = memory[pctr + 3];
  52.  
  53.                         var result = x1 + x2;
  54.                         memory[pout] = result;
  55.                         pctr += 4;
  56.  
  57.                         log($"Set {pout} to {x1}+{x2}={result}");
  58.                         break;
  59.                     }
  60.  
  61.                     case 2:
  62.                     {
  63.                         var x1 = resolveParam(0, pctr, memory);
  64.                         var x2 = resolveParam(1, pctr, memory);
  65.                         var pout = memory[pctr + 3];
  66.  
  67.                         var result = x1 * x2;
  68.                         memory[pout] = result;
  69.                         pctr += 4;
  70.  
  71.                         log($"Set {pout} to {x1}*{x2}={result}");
  72.                         break;
  73.                     }
  74.  
  75.                     case 3:
  76.                     {
  77.                         var pout = memory[pctr + 1];
  78.                         var val = input();
  79.                         memory[pout] = val;
  80.                         pctr += 2;
  81.  
  82.                         log($"Set {pout} to (input) {val}");
  83.                         break;
  84.                     }
  85.  
  86.                     case 4:
  87.                     {
  88.                         var x = resolveParam(0, pctr, memory);
  89.                         output(x);
  90.                         pctr += 2;
  91.  
  92.                         log($"Output {x}");
  93.                         break;
  94.                     }
  95.  
  96.                     case 5:
  97.                     {
  98.                         var x = resolveParam(0, pctr, memory);
  99.  
  100.                         if (x != 0)
  101.                         {
  102.                             pctr = resolveParam(1, pctr, memory);
  103.                             log($"{x} != 0; jumping to {pctr}");
  104.                         }
  105.                         else
  106.                         {
  107.                             log($"{x} == 0; noop");
  108.                             pctr += 3;
  109.                         }
  110.  
  111.                         break;
  112.                     }
  113.  
  114.                     case 6:
  115.                     {
  116.                         var x = resolveParam(0, pctr, memory);
  117.  
  118.                         if (x == 0)
  119.                         {
  120.                             pctr = resolveParam(1, pctr, memory);
  121.                             log($"{x} == 0; jumping to {pctr}");
  122.                         }
  123.                         else
  124.                         {
  125.                             log($"{x} != 0; noop");
  126.                             pctr += 3;
  127.                         }
  128.  
  129.                         break;
  130.                     }
  131.  
  132.                     case 7:
  133.                     {
  134.                         var x1 = resolveParam(0, pctr, memory);
  135.                         var x2 = resolveParam(1, pctr, memory);
  136.                         var pOut = memory[pctr + 3];
  137.  
  138.                         var result = (x1 < x2) ? 1 : 0;
  139.                         memory[pOut] = result;
  140.  
  141.                         log($"Set {pOut} to {result} ({x1} < {x2}?)");
  142.  
  143.                         pctr += 4;
  144.                         break;
  145.                     }
  146.  
  147.                     case 8:
  148.                     {
  149.                         var x1 = resolveParam(0, pctr, memory);
  150.                         var x2 = resolveParam(1, pctr, memory);
  151.                         var pOut = memory[pctr + 3];
  152.  
  153.                         var result = (x1 == x2) ? 1 : 0;
  154.                         memory[pOut] = result;
  155.  
  156.                         log($"Set {pOut} to {result} ({x1} = {x2}?)");
  157.  
  158.                         pctr += 4;
  159.                         break;
  160.                     }
  161.  
  162.                     case 99:
  163.                     {
  164.                         running = false;
  165.                         log($"Stopping");
  166.                         break;
  167.                     }
  168.  
  169.                     default: throw new Exception($"Unknown instr {instr}");
  170.                 }
  171.  
  172.             }
  173.  
  174.             return memory;
  175.         }
  176.     }
  177. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement