day 9, refactor IntCodeVM
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
cd816151aa
commit
fc102fe601
8
Day7.cs
8
Day7.cs
|
@ -9,11 +9,11 @@ namespace aoc2019
|
|||
{
|
||||
public override int DayNumber => 7;
|
||||
|
||||
private readonly List<int> input;
|
||||
private readonly List<long> input;
|
||||
private readonly IntCodeVM[] Amplifiers = new IntCodeVM[5];
|
||||
public Day7()
|
||||
{
|
||||
input = Input.First().Split(',').Select(int.Parse).ToList();
|
||||
input = Input.First().Split(',').Select(long.Parse).ToList();
|
||||
for (var i = 0; i < 5; i++) Amplifiers[i] = new IntCodeVM(input);
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ namespace aoc2019
|
|||
|
||||
public override string Part1()
|
||||
{
|
||||
int i, largest = 0;
|
||||
long i, largest = 0;
|
||||
|
||||
foreach (var phaseSeq in Enumerable.Range(0, 5).Permute())
|
||||
{
|
||||
|
@ -42,7 +42,7 @@ namespace aoc2019
|
|||
|
||||
public override string Part2()
|
||||
{
|
||||
int i, largest = 0;
|
||||
long i, largest = 0;
|
||||
|
||||
foreach (var phaseSeq in Enumerable.Range(5, 5).Permute())
|
||||
{
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
using aoc2019.lib;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace aoc2019
|
||||
{
|
||||
internal class Day9 : Day
|
||||
{
|
||||
public override int DayNumber => 9;
|
||||
private readonly IntCodeVM vm;
|
||||
|
||||
public Day9()
|
||||
{
|
||||
vm = new IntCodeVM(Input.First().Split(',').Select(long.Parse).ToList());
|
||||
}
|
||||
|
||||
public override string Part1()
|
||||
{
|
||||
vm.Reset();
|
||||
vm.Run(1);
|
||||
return $"{vm.output.ToDelimitedString(",")}";
|
||||
}
|
||||
|
||||
public override string Part2()
|
||||
{
|
||||
vm.Reset();
|
||||
vm.Run(2);
|
||||
return $"{vm.output.ToDelimitedString(",")}";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,28 +7,31 @@
|
|||
|
||||
<ItemGroup>
|
||||
<None Update="input\day1.in">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="input\day2.in">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="input\day3.in">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="input\day4.in">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="input\day5.in">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="input\day6.in">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="input\day7.in">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="input\day8.in">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="input\day9.in">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
1102,34463338,34463338,63,1007,63,34463338,63,1005,63,53,1101,0,3,1000,109,988,209,12,9,1000,209,6,209,3,203,0,1008,1000,1,63,1005,63,65,1008,1000,2,63,1005,63,904,1008,1000,0,63,1005,63,58,4,25,104,0,99,4,0,104,0,99,4,17,104,0,99,0,0,1101,0,252,1023,1101,0,0,1020,1102,1,39,1013,1102,1,234,1029,1102,26,1,1016,1101,37,0,1005,1101,0,27,1011,1101,21,0,1000,1101,0,29,1019,1101,35,0,1003,1102,22,1,1007,1102,1,32,1001,1101,1,0,1021,1102,1,216,1027,1102,30,1,1012,1102,1,24,1009,1101,36,0,1002,1101,0,31,1010,1101,0,243,1028,1102,787,1,1024,1102,255,1,1022,1102,33,1,1017,1102,1,23,1004,1102,778,1,1025,1102,1,28,1008,1101,0,223,1026,1102,1,25,1015,1101,0,20,1006,1102,34,1,1014,1101,38,0,1018,109,-4,1202,5,1,63,1008,63,32,63,1005,63,203,4,187,1106,0,207,1001,64,1,64,1002,64,2,64,109,37,2106,0,-6,1001,64,1,64,1106,0,225,4,213,1002,64,2,64,109,3,2106,0,-8,4,231,1001,64,1,64,1105,1,243,1002,64,2,64,109,-12,2105,1,-1,1105,1,261,4,249,1001,64,1,64,1002,64,2,64,109,-13,2102,1,-3,63,1008,63,31,63,1005,63,285,1001,64,1,64,1106,0,287,4,267,1002,64,2,64,109,6,21102,40,1,0,1008,1017,40,63,1005,63,313,4,293,1001,64,1,64,1105,1,313,1002,64,2,64,109,-10,2107,31,-6,63,1005,63,331,4,319,1105,1,335,1001,64,1,64,1002,64,2,64,109,-6,2102,1,7,63,1008,63,28,63,1005,63,357,4,341,1105,1,361,1001,64,1,64,1002,64,2,64,109,2,21107,41,40,8,1005,1011,377,1106,0,383,4,367,1001,64,1,64,1002,64,2,64,109,-1,1201,2,0,63,1008,63,26,63,1005,63,403,1106,0,409,4,389,1001,64,1,64,1002,64,2,64,109,22,1205,-4,425,1001,64,1,64,1105,1,427,4,415,1002,64,2,64,109,-9,21101,42,0,3,1008,1018,39,63,1005,63,451,1001,64,1,64,1105,1,453,4,433,1002,64,2,64,109,3,21107,43,44,0,1005,1018,475,4,459,1001,64,1,64,1105,1,475,1002,64,2,64,109,-7,21101,44,0,0,1008,1011,44,63,1005,63,497,4,481,1105,1,501,1001,64,1,64,1002,64,2,64,109,17,1206,-7,513,1105,1,519,4,507,1001,64,1,64,1002,64,2,64,109,-24,1207,5,25,63,1005,63,537,4,525,1105,1,541,1001,64,1,64,1002,64,2,64,109,7,21108,45,43,2,1005,1013,557,1106,0,563,4,547,1001,64,1,64,1002,64,2,64,109,-5,1207,-3,34,63,1005,63,583,1001,64,1,64,1106,0,585,4,569,1002,64,2,64,109,5,21108,46,46,5,1005,1016,607,4,591,1001,64,1,64,1105,1,607,1002,64,2,64,109,-12,2108,20,8,63,1005,63,627,1001,64,1,64,1105,1,629,4,613,1002,64,2,64,109,24,1206,-3,647,4,635,1001,64,1,64,1105,1,647,1002,64,2,64,109,-30,2108,32,8,63,1005,63,665,4,653,1106,0,669,1001,64,1,64,1002,64,2,64,109,22,1208,-9,20,63,1005,63,691,4,675,1001,64,1,64,1106,0,691,1002,64,2,64,109,-4,21102,47,1,3,1008,1014,49,63,1005,63,715,1001,64,1,64,1105,1,717,4,697,1002,64,2,64,109,-10,2101,0,1,63,1008,63,36,63,1005,63,743,4,723,1001,64,1,64,1105,1,743,1002,64,2,64,109,16,1201,-9,0,63,1008,63,28,63,1005,63,769,4,749,1001,64,1,64,1105,1,769,1002,64,2,64,109,2,2105,1,5,4,775,1001,64,1,64,1106,0,787,1002,64,2,64,109,-5,1202,-6,1,63,1008,63,26,63,1005,63,807,1106,0,813,4,793,1001,64,1,64,1002,64,2,64,109,-16,2107,37,4,63,1005,63,833,1001,64,1,64,1105,1,835,4,819,1002,64,2,64,109,2,2101,0,1,63,1008,63,34,63,1005,63,855,1105,1,861,4,841,1001,64,1,64,1002,64,2,64,109,19,1205,2,875,4,867,1105,1,879,1001,64,1,64,1002,64,2,64,109,-2,1208,-8,23,63,1005,63,899,1001,64,1,64,1106,0,901,4,885,4,64,99,21101,0,27,1,21102,915,1,0,1106,0,922,21201,1,61455,1,204,1,99,109,3,1207,-2,3,63,1005,63,964,21201,-2,-1,1,21102,942,1,0,1105,1,922,22102,1,1,-1,21201,-2,-3,1,21102,1,957,0,1105,1,922,22201,1,-1,-2,1106,0,968,22101,0,-2,-2,109,-3,2105,1,0
|
132
lib/IntCodeVM.cs
132
lib/IntCodeVM.cs
|
@ -1,22 +1,25 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace aoc2019.lib
|
||||
{
|
||||
public class IntCodeVM
|
||||
{
|
||||
private int i;
|
||||
public List<int> v;
|
||||
public Queue<int> input, output;
|
||||
private readonly List<int> program;
|
||||
private long i;
|
||||
private long relbase;
|
||||
public long[] memory;
|
||||
private readonly long[] program;
|
||||
public Queue<long> input, output;
|
||||
|
||||
public IntCodeVM(List<int> tape)
|
||||
public IntCodeVM(List<long> tape)
|
||||
{
|
||||
i = 0;
|
||||
program = tape;
|
||||
v = tape;
|
||||
input = new Queue<int>();
|
||||
output = new Queue<int>();
|
||||
relbase = 0;
|
||||
program = tape.ToArray();
|
||||
memory = tape.ToArray();
|
||||
input = new Queue<long>();
|
||||
output = new Queue<long>();
|
||||
}
|
||||
|
||||
public enum HaltType
|
||||
|
@ -25,66 +28,107 @@ namespace aoc2019.lib
|
|||
Waiting
|
||||
}
|
||||
|
||||
enum Op : int
|
||||
{
|
||||
ADD = 1, MUL = 2, INPUT = 3, OUTPUT = 4, JMP = 5, JNE = 6, LT = 7, EQ = 8, HALT = 99
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
i = 0;
|
||||
v = program;
|
||||
relbase = 0;
|
||||
memory = program;
|
||||
input.Clear();
|
||||
output.Clear();
|
||||
}
|
||||
|
||||
public int Result => output.Dequeue();
|
||||
public long Result => output.Dequeue();
|
||||
|
||||
public HaltType Run(params int[] additionalInput)
|
||||
private long MemGet(long addr)
|
||||
{
|
||||
foreach (var i in additionalInput) input.Enqueue(i);
|
||||
return addr < memory.Length ? memory[addr] : 0;
|
||||
}
|
||||
|
||||
private void MemSet(long addr, long value)
|
||||
{
|
||||
if (addr < 0) addr = 0;
|
||||
if (addr >= memory.Length)
|
||||
Array.Resize(ref memory, (int)addr + 1);
|
||||
memory[addr] = value;
|
||||
}
|
||||
|
||||
private long Mode(long idx)
|
||||
{
|
||||
var mode = MemGet(i) / 100;
|
||||
for (var s = 1; s < idx; s++)
|
||||
mode /= 10;
|
||||
return mode % 10;
|
||||
}
|
||||
|
||||
private long Get(long idx)
|
||||
{
|
||||
var param = MemGet(i + idx);
|
||||
switch (Mode(idx))
|
||||
{
|
||||
case 0: return MemGet(param);
|
||||
case 1: return param;
|
||||
case 2: return MemGet(relbase + param);
|
||||
default: throw new Exception("invalid parameter mode");
|
||||
}
|
||||
}
|
||||
|
||||
private void Set(long idx, long val)
|
||||
{
|
||||
var param = MemGet(i + idx);
|
||||
switch (Mode(idx))
|
||||
{
|
||||
case 0: MemSet(param, val); break;
|
||||
case 1: throw new Exception("cannot set in immediate mode");
|
||||
case 2: MemSet(relbase + param, val); break;
|
||||
default: throw new Exception("invalid parameter mode");
|
||||
}
|
||||
}
|
||||
|
||||
public HaltType Run(params long[] additionalInput)
|
||||
{
|
||||
foreach (var s in additionalInput) input.Enqueue(s);
|
||||
return Run();
|
||||
}
|
||||
public HaltType Run()
|
||||
{
|
||||
while (i < v.Count)
|
||||
while (i < memory.Length)
|
||||
{
|
||||
int Val(int mode, int val) =>
|
||||
mode == 0 ? v[val] : val;
|
||||
|
||||
int Val1() => Val(v[i] / 100 % 10, v[i + 1]);
|
||||
int Val2() => Val(v[i] / 1000, v[i + 2]);
|
||||
|
||||
switch ((Op)(v[i] % 100))
|
||||
var op = MemGet(i) % 100;
|
||||
switch (op)
|
||||
{
|
||||
case Op.ADD:
|
||||
v[v[i + 3]] = Val1() + Val2();
|
||||
case 1:
|
||||
Set(3, Get(1) + Get(2));
|
||||
i += 4; break;
|
||||
case Op.MUL:
|
||||
v[v[i + 3]] = Val1() * Val2();
|
||||
case 2:
|
||||
Set(3, Get(1) * Get(2));
|
||||
i += 4; break;
|
||||
case Op.INPUT:
|
||||
case 3:
|
||||
if (!input.Any())
|
||||
return HaltType.Waiting;
|
||||
v[v[i + 1]] = input.Dequeue();
|
||||
Set(1, input.Dequeue());
|
||||
i += 2; break;
|
||||
case Op.OUTPUT:
|
||||
output.Enqueue(Val1());
|
||||
case 4:
|
||||
output.Enqueue(Get(1));
|
||||
i += 2; break;
|
||||
case Op.JMP:
|
||||
i = Val1() == 0 ? i + 3 : Val2();
|
||||
case 5:
|
||||
i = Get(1) == 0 ? i + 3 : Get(2);
|
||||
break;
|
||||
case Op.JNE:
|
||||
i = Val1() != 0 ? i + 3 : Val2();
|
||||
case 6:
|
||||
i = Get(1) != 0 ? i + 3 : Get(2);
|
||||
break;
|
||||
case Op.LT:
|
||||
v[v[i + 3]] = Val1() < Val2() ? 1 : 0;
|
||||
case 7:
|
||||
Set(3, Get(1) < Get(2) ? 1 : 0);
|
||||
i += 4; break;
|
||||
case Op.EQ:
|
||||
v[v[i + 3]] = Val1() == Val2() ? 1 : 0;
|
||||
case 8:
|
||||
Set(3, Get(1) == Get(2) ? 1 : 0);
|
||||
i += 4; break;
|
||||
case Op.HALT:
|
||||
case 9:
|
||||
relbase += Get(1);
|
||||
i += 2; break;
|
||||
case 99:
|
||||
return HaltType.Terminate;
|
||||
default:
|
||||
throw new Exception($"unknown op {op} at {i}");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue