diff --git a/Advent2020/Advent2020.csproj b/Advent2020/Advent2020.csproj index 4e82cb7..362f8d8 100644 --- a/Advent2020/Advent2020.csproj +++ b/Advent2020/Advent2020.csproj @@ -74,6 +74,7 @@ + @@ -100,12 +101,18 @@ PreserveNewest + + PreserveNewest + PreserveNewest PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/Advent2020/Data/Day08.txt b/Advent2020/Data/Day08.txt new file mode 100644 index 0000000..d51d76f --- /dev/null +++ b/Advent2020/Data/Day08.txt @@ -0,0 +1,591 @@ +acc -5 +acc +48 +acc -1 +acc +5 +jmp +426 +acc +8 +jmp +72 +acc +22 +nop +64 +acc +18 +jmp +447 +acc +9 +acc +21 +acc -1 +acc -18 +jmp +349 +jmp +475 +acc +10 +nop +273 +acc -12 +acc +16 +jmp +519 +jmp +315 +acc -15 +acc +7 +acc +41 +acc -3 +jmp +97 +acc +28 +jmp +245 +acc +20 +acc -13 +acc +14 +jmp +304 +acc +20 +nop +73 +acc +0 +jmp +308 +jmp +1 +acc +6 +acc -18 +nop -7 +jmp +327 +acc +39 +acc -14 +jmp +473 +jmp +1 +nop +31 +acc -17 +jmp +496 +nop +449 +jmp +163 +acc +50 +nop -31 +nop -11 +acc -7 +jmp +29 +nop +376 +nop +311 +acc +14 +acc -11 +jmp +24 +acc -13 +jmp +237 +jmp +518 +jmp +246 +jmp +380 +acc +40 +acc +17 +acc +42 +acc -14 +jmp +293 +acc +8 +acc +25 +acc +9 +nop +251 +jmp +464 +jmp +409 +jmp +452 +jmp +1 +acc -6 +jmp +230 +jmp +106 +acc -13 +jmp +40 +jmp +452 +acc +16 +jmp +37 +acc -11 +jmp +118 +acc -5 +nop +322 +acc +4 +jmp +425 +nop +61 +nop +190 +acc +37 +acc +44 +jmp +275 +acc +32 +jmp -78 +jmp +485 +nop -1 +acc +50 +jmp +424 +jmp +423 +acc +23 +jmp +460 +acc -11 +acc +10 +jmp -67 +acc -14 +acc -14 +acc +39 +acc -6 +jmp +331 +acc +12 +acc +7 +acc +29 +jmp +65 +nop -26 +jmp +1 +acc +45 +jmp +188 +acc +23 +acc +42 +acc +18 +acc +34 +jmp -94 +acc +35 +acc +0 +nop +282 +acc +33 +jmp +297 +acc +10 +acc +16 +jmp +142 +acc -9 +jmp +9 +acc +35 +jmp +15 +jmp +1 +acc -19 +acc +18 +jmp +156 +jmp +230 +jmp +421 +acc +33 +acc -2 +acc +24 +acc +17 +jmp -66 +acc +32 +acc +38 +jmp -76 +acc +13 +jmp +74 +acc +30 +acc +49 +jmp +220 +nop -44 +acc +36 +nop -23 +nop -29 +jmp +157 +acc -3 +acc -13 +jmp -124 +nop +350 +acc +29 +acc +7 +acc +42 +jmp +282 +acc -4 +acc +33 +acc +50 +acc +1 +jmp +101 +acc +13 +nop +369 +acc -11 +acc -2 +jmp +56 +jmp -5 +acc -1 +acc -1 +jmp +52 +jmp +246 +acc +38 +acc -11 +jmp +30 +acc +18 +nop +15 +jmp +67 +jmp -112 +acc -14 +jmp -8 +nop -73 +jmp +4 +acc +0 +nop +111 +jmp +317 +acc -17 +nop +108 +jmp +91 +acc +9 +jmp +324 +acc +35 +acc +9 +acc +31 +nop +208 +jmp +177 +acc -17 +jmp -135 +jmp +46 +nop +145 +acc +41 +acc -4 +acc -17 +jmp -147 +acc +8 +jmp +357 +acc +25 +jmp +231 +acc -19 +acc +46 +jmp +268 +acc -18 +acc +34 +jmp +3 +jmp -83 +jmp +294 +jmp +89 +nop +27 +acc +32 +acc -1 +acc +5 +jmp +230 +acc +9 +nop -92 +jmp -146 +acc +16 +nop +91 +jmp +251 +jmp +1 +acc +50 +jmp -49 +acc +28 +nop -60 +jmp -29 +nop +328 +acc -13 +jmp +115 +jmp +160 +jmp +1 +acc +34 +acc +44 +acc -18 +jmp +40 +jmp +305 +acc -18 +acc +44 +jmp -174 +acc +15 +nop -62 +jmp +275 +nop +34 +nop +59 +acc +27 +jmp -212 +acc +8 +acc +36 +acc +2 +jmp +27 +jmp -240 +acc +10 +acc +22 +jmp +225 +acc -13 +jmp +246 +jmp -230 +jmp +120 +acc -14 +acc -19 +jmp +261 +acc +8 +jmp -170 +acc -17 +acc +33 +acc +43 +jmp +16 +acc +6 +acc +25 +jmp +140 +jmp +12 +jmp -101 +acc +1 +jmp +67 +jmp +141 +jmp +219 +jmp -46 +acc +20 +acc +6 +acc +39 +acc +43 +jmp +32 +acc +46 +jmp -41 +acc -1 +acc +48 +jmp +220 +acc +13 +acc +33 +acc -9 +nop -206 +jmp -137 +acc +35 +acc +11 +acc -12 +acc -2 +jmp +1 +acc +11 +acc +15 +jmp -73 +jmp +1 +jmp +142 +jmp +1 +acc +29 +acc -7 +acc +45 +jmp -302 +acc -9 +jmp +5 +acc +14 +acc +5 +jmp -313 +jmp -86 +acc -11 +acc +13 +acc +3 +jmp +171 +acc -8 +acc +47 +nop +205 +jmp +181 +acc -19 +acc +26 +jmp -340 +acc +31 +acc +45 +acc +16 +acc +16 +jmp -41 +acc +44 +jmp +76 +acc +0 +acc +47 +acc +9 +acc -12 +jmp +159 +acc +21 +jmp -50 +jmp +1 +jmp -18 +acc +46 +jmp -5 +jmp +120 +jmp +51 +jmp +123 +acc +28 +nop -288 +jmp -293 +jmp -39 +jmp -309 +jmp -206 +jmp -274 +acc -10 +acc +39 +jmp +124 +acc +6 +acc -12 +acc -12 +jmp -294 +acc +30 +acc +42 +acc +30 +acc -17 +jmp -227 +nop -241 +acc +46 +jmp -64 +nop -106 +nop -25 +acc +48 +acc +48 +jmp -323 +acc +30 +acc -10 +jmp -382 +acc +44 +jmp -21 +acc -6 +jmp -102 +acc -17 +acc -13 +acc +23 +jmp -199 +acc +7 +acc +28 +acc +43 +jmp -186 +nop -105 +jmp -390 +acc +29 +nop +168 +acc +49 +jmp -9 +jmp -335 +acc +4 +jmp -86 +nop -348 +acc -17 +acc -12 +jmp +107 +acc +28 +jmp -72 +acc +17 +acc +31 +nop -10 +jmp -295 +acc +41 +jmp -271 +jmp -350 +nop -64 +acc -11 +acc +6 +jmp -198 +acc -5 +jmp -206 +acc +23 +jmp -390 +jmp +1 +jmp +1 +acc +9 +nop -91 +jmp -15 +acc +36 +acc +27 +acc +42 +jmp +18 +acc +20 +acc +10 +acc +44 +jmp +46 +jmp +110 +acc +31 +jmp -371 +acc +13 +acc -16 +nop -245 +acc +30 +jmp +38 +acc -6 +acc -14 +acc +21 +acc +46 +jmp -206 +acc +35 +acc +25 +acc +22 +acc -9 +jmp -92 +acc +20 +nop -113 +nop -189 +jmp -453 +acc +43 +acc -18 +acc -19 +acc -4 +jmp -364 +acc +35 +acc +44 +acc +19 +acc -13 +jmp -297 +acc -11 +acc +36 +nop -92 +jmp -93 +jmp -330 +acc +40 +jmp -248 +jmp -255 +acc +36 +acc +32 +jmp -190 +acc -15 +jmp -187 +jmp -23 +nop -268 +jmp -203 +acc -10 +acc +14 +acc -17 +nop -400 +jmp +61 +nop +60 +acc +17 +acc -9 +jmp -409 +acc +0 +acc +13 +acc +47 +acc -6 +jmp -102 +acc +37 +jmp -257 +acc -1 +acc +41 +acc +25 +jmp -397 +acc +9 +acc +31 +jmp -48 +acc -11 +jmp -332 +jmp -433 +jmp +30 +jmp +38 +acc +17 +nop -376 +nop -93 +acc +50 +jmp -249 +acc -10 +jmp -225 +acc +10 +jmp +35 +jmp -475 +acc +18 +jmp -250 +acc -12 +acc +25 +jmp -450 +jmp -411 +acc +45 +jmp -117 +acc -6 +acc +30 +acc -6 +nop -313 +jmp -271 +acc +22 +acc +13 +acc -12 +acc +4 +jmp -379 +acc +36 +acc +17 +acc +15 +acc +47 +jmp -417 +jmp +4 +jmp -332 +acc +23 +jmp -336 +acc +34 +acc +1 +acc +50 +acc +7 +jmp -466 +jmp -70 +acc +4 +nop +8 +acc +18 +jmp -28 +jmp -47 +jmp -410 +acc -1 +acc +3 +jmp -90 +acc +12 +acc +41 +jmp -98 +jmp -55 +acc +17 +nop -85 +acc +48 +acc +50 +jmp +1 \ No newline at end of file diff --git a/Advent2020/Data/Day08_test.txt b/Advent2020/Data/Day08_test.txt new file mode 100644 index 0000000..7e3c218 --- /dev/null +++ b/Advent2020/Data/Day08_test.txt @@ -0,0 +1,9 @@ +nop +0 +acc +1 +jmp +4 +acc +3 +jmp -3 +acc -99 +acc +1 +jmp -4 +acc +6 \ No newline at end of file diff --git a/Advent2020/Day08.cs b/Advent2020/Day08.cs new file mode 100644 index 0000000..405f8ff --- /dev/null +++ b/Advent2020/Day08.cs @@ -0,0 +1,146 @@ +using FluentAssertions; +using System.Collections.Generic; +using Utils; +using Xunit; + +namespace Advent2020 +{ + public class Day08 + { + enum OpCode + { + NOP, + ACC, + JMP + } + + struct Instruction + { + readonly public OpCode OpCode; + readonly public long Value; + + public Instruction(OpCode opCode, long value) + { + OpCode = opCode; + Value = value; + } + } + + class VmState + { + public long Acc = 0; + public long Ip = 0; + } + + Instruction[] LoadProgram(string input) + { + var program = new List(); + + foreach (var line in FileIterator.Lines(input)) + { + var split = line.Split(' '); + OpCode opCode = OpCode.NOP; + switch (split[0]) + { + case "acc": opCode = OpCode.ACC; break; + case "jmp": opCode = OpCode.JMP; break; + } + + var value = long.Parse(split[1]); + program.Add(new Instruction(opCode, value)); + } + + return program.ToArray(); + } + + void ExecuteUntilLoop(VmState vmState, Instruction[] program) + { + var visited = new HashSet(); + + while (true) + { + if (vmState.Ip >= program.Length) return; + if (visited.Contains(vmState.Ip)) throw new Utils.VM.Halt(); + visited.Add(vmState.Ip); + var instruction = program[vmState.Ip]; + + switch (instruction.OpCode) + { + case OpCode.NOP: + break; + + case OpCode.ACC: + vmState.Acc += instruction.Value; + break; + + case OpCode.JMP: + vmState.Ip += (instruction.Value - 1); // We need to take into account that the IP is auto incremented + break; + } + + vmState.Ip++; + } + } + + long PatchAndExecute(Instruction[] program) + { + for (var i = 0; i < program.Length; i++) + { + var patchedInstruction = program[i]; + switch (patchedInstruction.OpCode) + { + case OpCode.NOP: + program[i] = new Instruction(OpCode.JMP, patchedInstruction.Value); + break; + + case OpCode.JMP: + program[i] = new Instruction(OpCode.NOP, patchedInstruction.Value); + break; + + default: + continue; + } + + try + { + var vmState = new VmState(); + ExecuteUntilLoop(vmState, program); + return vmState.Acc; + } + catch (Utils.VM.Halt) {} // Loop detected, so continue the search... + + // Restore the program + program[i] = patchedInstruction; + } + throw new Expletive("Fuck"); + } + + [Theory] + [InlineData("Data/Day08_test.txt", 5)] + [InlineData("Data/Day08.txt", 1420)] + public void Problem1(string input, long expected) + { + var vmState = new VmState(); + var prog = LoadProgram(input); + + try + { + ExecuteUntilLoop(vmState, prog); + Oh.Bugger(); + } + catch (Utils.VM.Halt) + { + vmState.Acc.Should().Be(expected); + } + } + + [Theory] + [InlineData("Data/Day08_test.txt", 8)] + [InlineData("Data/Day08.txt", 1245)] + public void Problem2(string input, int expected) + { + var program = LoadProgram(input); + PatchAndExecute(program).Should().Be(expected); + } + } +}