diff --git a/Advent.csproj.DotSettings b/Advent.csproj.DotSettings index f5ebb6d..43a0cbb 100644 --- a/Advent.csproj.DotSettings +++ b/Advent.csproj.DotSettings @@ -4,4 +4,5 @@ True True True - True \ No newline at end of file + True + True \ No newline at end of file diff --git a/Day7/Day7.cs b/Day7/Day7.cs new file mode 100644 index 0000000..a380701 --- /dev/null +++ b/Day7/Day7.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Advent +{ + public static class Day7 + { + 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 phaseList = GetPhaseList(); + + int? max = 0; + + var amp = new IntcodeComputer(); + + foreach (var phases in phaseList) + { + var output = amp.Execute(new[] { phases[0], 0 }, program); + 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) + max = output; + } + + Console.WriteLine(max); + } + + private static IEnumerable GetPhaseList() + { + // This is a stupid brute force way to do it but I'm lazy and it is fast so good enough + + var phaseList = new List(); + + for (var i = 0; i <= 99999; i++) + { + var phases = i.ToString("00000").ToCharArray().Select(c => int.Parse(c.ToString())).ToArray(); + + if (phases.All(p => p <= 4) && phases.Distinct().Count() == 5) + phaseList.Add(phases); + } + + return phaseList; + } + } +} diff --git a/IntcodeComputer.cs b/IntcodeComputer.cs new file mode 100644 index 0000000..df2f8f8 --- /dev/null +++ b/IntcodeComputer.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Advent +{ + public class IntcodeComputer + { + private enum ParameterMode + { + Position, + Immediate + } + + private static int GetValue(IReadOnlyList codes, int parameter, ParameterMode mode) + { + return mode == ParameterMode.Immediate ? parameter : codes[parameter]; + } + + public int? Execute(int[] inputs, string commands) + { + var codes = commands.Split(',').Select(int.Parse).ToArray(); + + var position = 0; + var done = false; + var inputIndex = 0; + int? output = null; + + while (!done) + { + var (mode1, mode2, mode3, opCode) = ParseOpCode(codes[position]); + + switch (opCode) + { + case 1: + codes[codes[position + 3]] = GetValue(codes, codes[position + 1], mode1) + GetValue(codes, codes[position + 2], mode2); + + position += 4; + + break; + + case 2: + codes[codes[position + 3]] = GetValue(codes, codes[position + 1], mode1) * GetValue(codes, codes[position + 2], mode2); + + position += 4; + + break; + + case 3: + codes[codes[position + 1]] = inputs[inputIndex++]; + + position += 2; + + break; + + case 4: + output = GetValue(codes, codes[position + 1], ParameterMode.Position); + + position += 2; + + break; + + case 5: + { + var value = GetValue(codes, codes[position + 1], mode1); + + if (value != 0) + position = GetValue(codes, codes[position + 2], mode2); + else + position += 3; + } + + break; + + case 6: + { + var value = GetValue(codes, codes[position + 1], mode1); + + if (value == 0) + position = GetValue(codes, codes[position + 2], mode2); + else + position += 3; + } + + break; + + case 7: + { + var value1 = GetValue(codes, codes[position + 1], mode1); + var value2 = GetValue(codes, codes[position + 2], mode2); + + if (value1 < value2) + codes[codes[position + 3]] = 1; + else + codes[codes[position + 3]] = 0; + + position += 4; + } + + break; + + case 8: + { + var value1 = GetValue(codes, codes[position + 1], mode1); + var value2 = GetValue(codes, codes[position + 2], mode2); + + if (value1 == value2) + codes[codes[position + 3]] = 1; + else + codes[codes[position + 3]] = 0; + + position += 4; + } + + break; + + case 99: + done = true; + + break; + } + } + + return output; + } + + private static (ParameterMode mode1, ParameterMode mode2, ParameterMode mode3, int opCode) ParseOpCode(int fullOpCode) + { + var codeString = fullOpCode.ToString("00000").ToCharArray(); + + var mode1 = Enum.Parse(codeString[2].ToString()); + var mode2 = Enum.Parse(codeString[1].ToString()); + var mode3 = Enum.Parse(codeString[0].ToString()); + + var opCode = int.Parse(codeString[3].ToString() + codeString[4]); + + return (mode1, mode2, mode3, opCode); + } + } +} diff --git a/Program.cs b/Program.cs index 95a1411..7c18d4b 100644 --- a/Program.cs +++ b/Program.cs @@ -9,7 +9,8 @@ //Day3.Execute(); //Day4.Execute(); //Day5.Execute(); - Day6.Execute(); + //Day6.Execute(); + Day7.Execute(); } } }