mirror of
https://github.com/ckaczor/Advent2019.git
synced 2026-02-17 02:51:35 -05:00
Day 7 - Part 2
This commit is contained in:
33
Day7/Day7.cs
33
Day7/Day7.cs
@@ -9,23 +9,34 @@ namespace Advent
|
|||||||
public static void Execute()
|
public static void Execute()
|
||||||
{
|
{
|
||||||
var program = "3,8,1001,8,10,8,105,1,0,0,21,34,43,64,85,98,179,260,341,422,99999,3,9,1001,9,3,9,102,3,9,9,4,9,99,3,9,102,5,9,9,4,9,99,3,9,1001,9,2,9,1002,9,4,9,1001,9,3,9,1002,9,4,9,4,9,99,3,9,1001,9,3,9,102,3,9,9,101,4,9,9,102,3,9,9,4,9,99,3,9,101,2,9,9,1002,9,3,9,4,9,99,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,99,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,99,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,99,3,9,101,1,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1002,9,2,9,4,9,99,3,9,101,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,99";
|
var program = "3,8,1001,8,10,8,105,1,0,0,21,34,43,64,85,98,179,260,341,422,99999,3,9,1001,9,3,9,102,3,9,9,4,9,99,3,9,102,5,9,9,4,9,99,3,9,1001,9,2,9,1002,9,4,9,1001,9,3,9,1002,9,4,9,4,9,99,3,9,1001,9,3,9,102,3,9,9,101,4,9,9,102,3,9,9,4,9,99,3,9,101,2,9,9,1002,9,3,9,4,9,99,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,99,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,99,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,99,3,9,101,1,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1002,9,2,9,4,9,99,3,9,101,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,99";
|
||||||
|
|
||||||
var phaseList = GetPhaseList();
|
var phaseList = GetPhaseList();
|
||||||
|
|
||||||
|
//var program = "3,52,1001,52,-5,52,3,53,1,52,56,54,1007,54,5,55,1005,55,26,1001,54,-5,54,1105,1,12,1,53,54,53,1008,54,0,55,1001,55,1,55,2,53,55,53,4,53,1001,56,-1,56,1005,56,6,99,0,0,0,0,10";
|
||||||
|
//var phaseList = new List<int[]> { "9,7,8,5,6".Split(',').Select(c => int.Parse(c.ToString())).ToArray() };
|
||||||
|
|
||||||
int? max = 0;
|
int? max = 0;
|
||||||
|
|
||||||
var amp = new IntcodeComputer();
|
|
||||||
|
|
||||||
foreach (var phases in phaseList)
|
foreach (var phases in phaseList)
|
||||||
{
|
{
|
||||||
var output = amp.Execute(new[] { phases[0], 0 }, program);
|
var value = 0;
|
||||||
output = amp.Execute(new[] { phases[1], output.GetValueOrDefault(0) }, program);
|
|
||||||
output = amp.Execute(new[] { phases[2], output.GetValueOrDefault(0) }, program);
|
|
||||||
output = amp.Execute(new[] { phases[3], output.GetValueOrDefault(0) }, program);
|
|
||||||
output = amp.Execute(new[] { phases[4], output.GetValueOrDefault(0) }, program);
|
|
||||||
|
|
||||||
if (output > max)
|
var amp1 = new IntcodeComputer(program, phases[0]);
|
||||||
max = output;
|
var amp2 = new IntcodeComputer(program, phases[1]);
|
||||||
|
var amp3 = new IntcodeComputer(program, phases[2]);
|
||||||
|
var amp4 = new IntcodeComputer(program, phases[3]);
|
||||||
|
var amp5 = new IntcodeComputer(program, phases[4]);
|
||||||
|
|
||||||
|
while (!amp5.Halted)
|
||||||
|
{
|
||||||
|
value = amp1.Execute(value);
|
||||||
|
value = amp2.Execute(value);
|
||||||
|
value = amp3.Execute(value);
|
||||||
|
value = amp4.Execute(value);
|
||||||
|
value = amp5.Execute(value);
|
||||||
|
|
||||||
|
if (value > max)
|
||||||
|
max = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine(max);
|
Console.WriteLine(max);
|
||||||
@@ -41,7 +52,7 @@ namespace Advent
|
|||||||
{
|
{
|
||||||
var phases = i.ToString("00000").ToCharArray().Select(c => int.Parse(c.ToString())).ToArray();
|
var phases = i.ToString("00000").ToCharArray().Select(c => int.Parse(c.ToString())).ToArray();
|
||||||
|
|
||||||
if (phases.All(p => p <= 4) && phases.Distinct().Count() == 5)
|
if (phases.All(p => p >= 5) && phases.Distinct().Count() == 5)
|
||||||
phaseList.Add(phases);
|
phaseList.Add(phases);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,116 +12,128 @@ namespace Advent
|
|||||||
Immediate
|
Immediate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly int[] _memory;
|
||||||
|
private readonly int _phase;
|
||||||
|
|
||||||
|
private bool _setPhase;
|
||||||
|
private int _instructionPointer;
|
||||||
|
private int _output;
|
||||||
|
|
||||||
|
public bool Halted { get; private set; }
|
||||||
|
|
||||||
|
public IntcodeComputer(string memoryString, int phase)
|
||||||
|
{
|
||||||
|
_memory = memoryString.Split(',').Select(int.Parse).ToArray();
|
||||||
|
_phase = phase;
|
||||||
|
}
|
||||||
|
|
||||||
private static int GetValue(IReadOnlyList<int> codes, int parameter, ParameterMode mode)
|
private static int GetValue(IReadOnlyList<int> codes, int parameter, ParameterMode mode)
|
||||||
{
|
{
|
||||||
return mode == ParameterMode.Immediate ? parameter : codes[parameter];
|
return mode == ParameterMode.Immediate ? parameter : codes[parameter];
|
||||||
}
|
}
|
||||||
|
|
||||||
public int? Execute(int[] inputs, string commands)
|
public int Execute(int input)
|
||||||
{
|
{
|
||||||
var codes = commands.Split(',').Select(int.Parse).ToArray();
|
while (!Halted)
|
||||||
|
|
||||||
var position = 0;
|
|
||||||
var done = false;
|
|
||||||
var inputIndex = 0;
|
|
||||||
int? output = null;
|
|
||||||
|
|
||||||
while (!done)
|
|
||||||
{
|
{
|
||||||
var (mode1, mode2, mode3, opCode) = ParseOpCode(codes[position]);
|
var (mode1, mode2, mode3, opCode) = ParseOpCode(_memory[_instructionPointer]);
|
||||||
|
|
||||||
switch (opCode)
|
switch (opCode)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
codes[codes[position + 3]] = GetValue(codes, codes[position + 1], mode1) + GetValue(codes, codes[position + 2], mode2);
|
_memory[_memory[_instructionPointer + 3]] = GetValue(_memory, _memory[_instructionPointer + 1], mode1) + GetValue(_memory, _memory[_instructionPointer + 2], mode2);
|
||||||
|
|
||||||
position += 4;
|
_instructionPointer += 4;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
codes[codes[position + 3]] = GetValue(codes, codes[position + 1], mode1) * GetValue(codes, codes[position + 2], mode2);
|
_memory[_memory[_instructionPointer + 3]] = GetValue(_memory, _memory[_instructionPointer + 1], mode1) * GetValue(_memory, _memory[_instructionPointer + 2], mode2);
|
||||||
|
|
||||||
position += 4;
|
_instructionPointer += 4;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
codes[codes[position + 1]] = inputs[inputIndex++];
|
var inputValue = _setPhase ? input : _phase;
|
||||||
|
|
||||||
position += 2;
|
_setPhase = true;
|
||||||
|
|
||||||
|
_memory[_memory[_instructionPointer + 1]] = inputValue;
|
||||||
|
|
||||||
|
_instructionPointer += 2;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
output = GetValue(codes, codes[position + 1], ParameterMode.Position);
|
_output = GetValue(_memory, _memory[_instructionPointer + 1], ParameterMode.Position);
|
||||||
|
|
||||||
position += 2;
|
_instructionPointer += 2;
|
||||||
|
|
||||||
break;
|
return _output;
|
||||||
|
|
||||||
case 5:
|
case 5:
|
||||||
{
|
{
|
||||||
var value = GetValue(codes, codes[position + 1], mode1);
|
var value = GetValue(_memory, _memory[_instructionPointer + 1], mode1);
|
||||||
|
|
||||||
if (value != 0)
|
if (value != 0)
|
||||||
position = GetValue(codes, codes[position + 2], mode2);
|
_instructionPointer = GetValue(_memory, _memory[_instructionPointer + 2], mode2);
|
||||||
else
|
else
|
||||||
position += 3;
|
_instructionPointer += 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6:
|
case 6:
|
||||||
{
|
{
|
||||||
var value = GetValue(codes, codes[position + 1], mode1);
|
var value = GetValue(_memory, _memory[_instructionPointer + 1], mode1);
|
||||||
|
|
||||||
if (value == 0)
|
if (value == 0)
|
||||||
position = GetValue(codes, codes[position + 2], mode2);
|
_instructionPointer = GetValue(_memory, _memory[_instructionPointer + 2], mode2);
|
||||||
else
|
else
|
||||||
position += 3;
|
_instructionPointer += 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7:
|
case 7:
|
||||||
{
|
{
|
||||||
var value1 = GetValue(codes, codes[position + 1], mode1);
|
var value1 = GetValue(_memory, _memory[_instructionPointer + 1], mode1);
|
||||||
var value2 = GetValue(codes, codes[position + 2], mode2);
|
var value2 = GetValue(_memory, _memory[_instructionPointer + 2], mode2);
|
||||||
|
|
||||||
if (value1 < value2)
|
if (value1 < value2)
|
||||||
codes[codes[position + 3]] = 1;
|
_memory[_memory[_instructionPointer + 3]] = 1;
|
||||||
else
|
else
|
||||||
codes[codes[position + 3]] = 0;
|
_memory[_memory[_instructionPointer + 3]] = 0;
|
||||||
|
|
||||||
position += 4;
|
_instructionPointer += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 8:
|
case 8:
|
||||||
{
|
{
|
||||||
var value1 = GetValue(codes, codes[position + 1], mode1);
|
var value1 = GetValue(_memory, _memory[_instructionPointer + 1], mode1);
|
||||||
var value2 = GetValue(codes, codes[position + 2], mode2);
|
var value2 = GetValue(_memory, _memory[_instructionPointer + 2], mode2);
|
||||||
|
|
||||||
if (value1 == value2)
|
if (value1 == value2)
|
||||||
codes[codes[position + 3]] = 1;
|
_memory[_memory[_instructionPointer + 3]] = 1;
|
||||||
else
|
else
|
||||||
codes[codes[position + 3]] = 0;
|
_memory[_memory[_instructionPointer + 3]] = 0;
|
||||||
|
|
||||||
position += 4;
|
_instructionPointer += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 99:
|
case 99:
|
||||||
done = true;
|
Halted = true;
|
||||||
|
|
||||||
break;
|
return _output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
return _output;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static (ParameterMode mode1, ParameterMode mode2, ParameterMode mode3, int opCode) ParseOpCode(int fullOpCode)
|
private static (ParameterMode mode1, ParameterMode mode2, ParameterMode mode3, int opCode) ParseOpCode(int fullOpCode)
|
||||||
|
|||||||
Reference in New Issue
Block a user