This commit is contained in:
2020-12-08 06:29:34 +01:00
parent 906463d28a
commit 0a335ea6fb
3 changed files with 913 additions and 0 deletions

View File

@@ -0,0 +1,48 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace AdventOfCode2020.Tests
{
[TestClass()]
public class Day08_Tests
{
[TestMethod()]
public void ResolvePart1__Example()
{
var day = new Day08();
string result = day.ResolvePart1(new string[] {
"nop +0",
"acc +1",
"jmp +4",
"acc +3",
"jmp -3",
"acc -99",
"acc +1",
"jmp -4",
"acc +6",
});
Assert.AreEqual("5", result);
}
[TestMethod()]
public void ResolvePart2__Example()
{
var day = new Day08();
string result = day.ResolvePart2(new string[] {
"nop +0",
"acc +1",
"jmp +4",
"acc +3",
"jmp -3",
"acc -99",
"acc +1",
"jmp -4",
"acc +6",
});
Assert.AreEqual("8", result);
}
}
}

229
AdventOfCode2020/Day08.cs Normal file
View File

@@ -0,0 +1,229 @@
using System;
using System.Collections.Generic;
/*
--- Day 8: Handheld Halting ---
Your flight to the major airline hub reaches cruising altitude without incident. While you consider checking the in-flight menu for one of those drinks that come with a little umbrella, you are interrupted by the kid sitting next to you.
Their handheld game console won't turn on! They ask if you can take a look.
You narrow the problem down to a strange infinite loop in the boot code (your puzzle input) of the device. You should be able to fix it, but first you need to be able to run the code in isolation.
The boot code is represented as a text file with one instruction per line of text. Each instruction consists of an operation (acc, jmp, or nop) and an argument (a signed number like +4 or -20).
acc increases or decreases a single global value called the accumulator by the value given in the argument. For example, acc +7 would increase the accumulator by 7. The accumulator starts at 0. After an acc instruction, the instruction immediately below it is executed next.
jmp jumps to a new instruction relative to itself. The next instruction to execute is found using the argument as an offset from the jmp instruction; for example, jmp +2 would skip the next instruction, jmp +1 would continue to the instruction immediately below it, and jmp -20 would cause the instruction 20 lines above to be executed next.
nop stands for No OPeration - it does nothing. The instruction immediately below it is executed next.
For example, consider the following program:
nop +0
acc +1
jmp +4
acc +3
jmp -3
acc -99
acc +1
jmp -4
acc +6
These instructions are visited in this order:
nop +0 | 1
acc +1 | 2, 8(!)
jmp +4 | 3
acc +3 | 6
jmp -3 | 7
acc -99 |
acc +1 | 4
jmp -4 | 5
acc +6 |
First, the nop +0 does nothing. Then, the accumulator is increased from 0 to 1 (acc +1) and jmp +4 sets the next instruction to the other acc +1 near the bottom. After it increases the accumulator from 1 to 2, jmp -4 executes, setting the next instruction to the only acc +3. It sets the accumulator to 5, and jmp -3 causes the program to continue back at the first acc +1.
This is an infinite loop: with this sequence of jumps, the program will run forever. The moment the program tries to run any instruction a second time, you know it will never terminate.
Immediately before the program would run an instruction a second time, the value in the accumulator is 5.
Run your copy of the boot code. Immediately before any instruction is executed a second time, what value is in the accumulator?
--- Part Two ---
After some careful analysis, you believe that exactly one instruction is corrupted.
Somewhere in the program, either a jmp is supposed to be a nop, or a nop is supposed to be a jmp. (No acc instructions were harmed in the corruption of this boot code.)
The program is supposed to terminate by attempting to execute an instruction immediately after the last instruction in the file. By changing exactly one jmp or nop, you can repair the boot code and make it terminate correctly.
For example, consider the same program from above:
nop +0
acc +1
jmp +4
acc +3
jmp -3
acc -99
acc +1
jmp -4
acc +6
If you change the first instruction from nop +0 to jmp +0, it would create a single-instruction infinite loop, never leaving that instruction. If you change almost any of the jmp instructions, the program will still eventually find another jmp instruction and loop forever.
However, if you change the second-to-last instruction (from jmp -4 to nop -4), the program terminates! The instructions are visited in this order:
nop +0 | 1
acc +1 | 2
jmp +4 | 3
acc +3 |
jmp -3 |
acc -99 |
acc +1 | 4
nop -4 | 5
acc +6 | 6
After the last instruction (acc +6), the program terminates by attempting to run the instruction below the last instruction in the file. With this change, after the program terminates, the accumulator contains the value 8 (acc +1, acc +1, acc +6).
Fix the program so that it terminates normally by changing exactly one jmp (to nop) or nop (to jmp). What is the value of the accumulator after the program terminates?
*/
namespace AdventOfCode2020
{
public class Day08 : IDay
{
public string ResolvePart1(string[] inputs)
{
VM vm = new VM(inputs);
vm.Run();
return vm.Accumulator.ToString();
}
public string ResolvePart2(string[] inputs)
{
VM vm = new VM(inputs);
foreach (Instruction instruction in vm.Instructions)
{
if (instruction.OpCode == OpCode.Acc) { continue; }
if (instruction.OpCode == OpCode.Nop)
{
instruction.OpCode = OpCode.Jmp;
vm.Run();
if (vm.Ended) { break; }
instruction.OpCode = OpCode.Nop;
}
if (instruction.OpCode == OpCode.Jmp)
{
instruction.OpCode = OpCode.Nop;
vm.Run();
if (vm.Ended) { break; }
instruction.OpCode = OpCode.Jmp;
}
}
return vm.Accumulator.ToString();
}
public enum OpCode
{
Acc,
Jmp,
Nop,
};
public class Instruction
{
public OpCode OpCode { get; set; }
public int Value { get; set; }
public bool Executed { get; set; }
public Instruction(string input)
{
string[] parts = input.Split(' ');
if (parts[0] == "acc")
{
OpCode = OpCode.Acc;
}
if (parts[0] == "jmp")
{
OpCode = OpCode.Jmp;
}
if (parts[0] == "nop")
{
OpCode = OpCode.Nop;
}
if (parts[1].StartsWith("+"))
{
Value = Convert.ToInt32(parts[1].Substring(1));
}
else
{
Value = Convert.ToInt32(parts[1]);
}
Executed = false;
}
}
public class VM
{
public List<Instruction> Instructions { get; set; }
public int Accumulator { get; set; }
public bool Ended { get; set; }
public VM(string[] inputs)
{
Instructions = new List<Instruction>();
foreach (string input in inputs)
{
Instructions.Add(new Instruction(input));
}
Accumulator = 0;
Ended = false;
}
public void Run()
{
foreach (Instruction instruction in Instructions)
{
instruction.Executed = false;
}
Ended = false;
Accumulator = 0;
int idx = 0;
while (Instructions[idx].Executed == false)
{
Instruction currentInstruction = Instructions[idx];
if (currentInstruction.OpCode == OpCode.Acc)
{
Accumulator += currentInstruction.Value;
currentInstruction.Executed = true;
idx++;
}
if (currentInstruction.OpCode == OpCode.Jmp)
{
currentInstruction.Executed = true;
idx += currentInstruction.Value;
}
if (currentInstruction.OpCode == OpCode.Nop)
{
currentInstruction.Executed = true;
idx++;
}
if (idx >= Instructions.Count)
{
Ended = true;
break;
}
}
}
}
}
}

View File

@@ -0,0 +1,636 @@
acc -13
jmp +37
acc -19
jmp +1
jmp +1
jmp +413
acc +10
jmp +194
jmp +587
jmp +388
acc +48
nop +284
acc +35
jmp +239
acc +0
jmp +58
acc +22
acc +45
acc +25
acc +23
jmp +544
jmp +610
nop +273
jmp +554
jmp +584
acc +30
jmp +481
acc +29
jmp +342
acc +9
acc +23
nop +377
jmp +483
acc +33
jmp +128
nop +560
nop +437
jmp +485
acc +2
acc +30
jmp +456
acc +0
acc -15
nop +126
acc +47
jmp +299
acc +36
acc +9
jmp -21
acc +10
acc +26
acc -3
acc +31
jmp +337
nop +517
jmp +303
acc +20
nop -43
acc +30
acc +24
jmp +348
jmp +158
acc +23
acc +16
acc +40
jmp +1
jmp +465
acc +12
jmp +276
acc +0
acc +32
acc +43
jmp +487
acc +40
acc +49
nop +540
jmp +455
acc +24
jmp +481
acc +30
nop +256
acc +29
acc +14
jmp +390
jmp +1
acc -3
jmp +1
jmp +295
acc +6
acc +46
acc +16
nop +128
jmp -38
acc +0
acc +16
acc +10
jmp +185
acc -19
acc +0
acc +23
acc -16
jmp +180
acc +14
jmp +1
acc +31
acc -4
jmp +439
jmp +204
acc +50
acc +12
nop +154
jmp +474
acc -16
jmp +511
acc +6
acc +32
jmp +504
acc +17
acc +21
acc -18
jmp +298
acc -17
acc +16
acc +4
acc +18
jmp +18
acc -10
acc +26
acc +36
jmp +166
nop -109
jmp +266
acc -9
jmp +306
nop +324
acc +16
acc +33
acc +18
jmp -50
acc +25
jmp +196
acc +21
jmp +308
jmp +38
acc +27
jmp -48
acc +14
acc +46
acc +48
acc +15
jmp +223
acc +0
acc +12
jmp -115
acc +19
acc +27
acc +30
jmp +377
jmp -144
jmp +231
acc +1
jmp +410
acc +41
jmp +138
acc -13
acc -8
acc -7
acc +25
jmp +366
acc +8
jmp +182
acc +2
nop +104
acc +24
acc +21
jmp -43
acc -8
acc +37
acc +23
jmp +292
jmp +365
acc +33
nop -144
acc -10
jmp +387
acc +13
acc -6
acc -12
nop +134
jmp +345
acc +5
acc +16
acc +35
acc +50
jmp +250
acc +46
jmp +105
acc -6
nop -152
jmp +233
jmp -88
acc +39
jmp +59
acc -4
acc +47
jmp +165
acc +32
acc +49
acc +24
jmp +344
acc -5
acc +3
jmp +359
acc +27
jmp +72
acc +0
acc +16
acc +40
jmp +98
acc +2
acc +23
acc +48
acc +2
jmp -33
jmp -186
acc +27
nop -83
acc +2
acc +19
jmp -141
acc +39
acc +34
acc +33
jmp +282
jmp +306
acc +12
jmp +317
acc +32
acc +50
acc +17
jmp +52
acc +3
acc +35
jmp +328
acc +26
nop +163
acc +6
acc +19
jmp +154
acc +4
jmp +1
jmp +373
acc -12
acc +47
jmp +1
jmp -234
acc +45
acc +46
acc -14
acc +50
jmp -134
acc +26
jmp +128
jmp +233
acc +23
nop -133
jmp -154
jmp +260
acc +21
acc +14
nop -89
acc +9
jmp -113
acc +10
acc +5
jmp +127
acc -9
acc +2
jmp +286
nop +274
jmp +93
acc +46
acc +36
jmp +53
acc +30
jmp -126
acc +11
acc +11
acc +23
jmp +296
nop -100
jmp +304
jmp +219
acc +16
jmp -93
acc +12
jmp +1
jmp +205
acc +6
acc -11
jmp +202
jmp +107
jmp +1
jmp -224
acc +24
acc +50
acc +37
jmp +45
acc +25
acc -15
jmp -151
jmp +1
acc +47
jmp -196
jmp +1
jmp +300
jmp +116
acc +39
acc +0
nop -176
acc -7
jmp -53
acc +20
nop -216
nop +291
jmp +38
acc +0
acc +32
acc -19
jmp -28
jmp -176
acc +33
acc +11
acc +47
nop -58
jmp -203
acc +48
acc +50
acc +41
jmp -315
acc -12
acc +23
acc +32
jmp +210
acc +46
acc -11
acc -16
jmp +103
acc +25
nop +95
acc +9
jmp -117
nop +18
acc -19
acc +38
jmp -130
acc +22
jmp +25
nop +201
nop +205
acc +14
jmp -124
jmp -46
acc +9
jmp -257
acc -19
acc -17
acc +36
acc +24
jmp -210
jmp -231
acc +40
jmp +46
nop -192
acc -13
acc +7
acc +33
jmp +103
acc +18
acc +37
acc -14
jmp -11
acc +12
nop -240
acc +35
acc +33
jmp -274
acc -9
acc +24
jmp -128
nop -129
acc -17
jmp -62
acc +0
acc +42
nop +116
jmp -44
acc +16
jmp +179
acc -8
acc +8
jmp -149
acc +39
acc +2
acc +14
acc +12
jmp -373
jmp +76
jmp -232
jmp -385
acc +22
acc +41
acc +28
jmp -179
acc +0
acc +22
acc +15
jmp -291
acc -18
jmp -222
acc +45
acc -15
jmp +61
acc +10
acc +16
acc +43
jmp +177
acc +43
acc -12
acc +20
acc +27
jmp -13
acc -14
jmp -336
nop -158
acc +3
nop -409
acc +17
jmp -257
acc +0
nop +124
jmp +1
jmp +117
jmp -179
acc -17
acc -2
jmp +1
jmp -37
acc +42
jmp +175
acc -9
acc +12
acc +4
jmp +69
acc -7
jmp +1
acc +32
jmp +54
jmp -444
acc +7
jmp -87
acc -6
nop -323
acc +47
acc -5
jmp -143
jmp +1
nop -44
acc +27
acc +21
jmp -184
jmp -404
jmp -70
acc +32
jmp -13
acc +0
nop -452
acc +1
acc +31
jmp -77
jmp -401
acc +42
jmp -428
nop -120
acc -17
nop -75
acc +6
jmp +20
jmp -291
acc +7
jmp +37
acc +10
acc +15
jmp +1
acc +11
jmp -363
acc -14
nop -321
jmp -40
acc +41
acc +31
jmp +58
jmp -493
acc +32
acc -10
acc +44
jmp -211
acc +47
acc +23
jmp -241
jmp -224
acc -1
jmp -350
acc +8
jmp -280
acc -19
acc +0
acc +17
jmp -274
acc +27
acc +11
jmp -82
acc +48
acc +27
jmp -518
acc +3
jmp -124
jmp +1
jmp -490
acc +41
jmp -238
acc -6
jmp -386
jmp -189
acc -11
jmp +80
acc -8
acc +9
nop -99
jmp +56
acc -18
jmp -83
acc +28
acc +13
jmp -228
acc +32
acc +34
acc +3
jmp -272
nop -410
acc +13
acc -17
jmp -236
acc +45
acc +0
acc +19
nop +29
jmp +38
jmp -75
acc +7
acc +33
acc +40
jmp -180
jmp -557
acc +22
jmp -249
acc +44
acc +45
acc +2
acc -19
jmp -537
acc +44
acc +32
acc -14
acc +39
jmp -406
jmp -488
acc +14
acc +41
jmp -327
acc +17
acc +25
nop -573
acc +0
jmp -563
acc +18
nop -282
acc +13
acc +45
jmp -325
acc +41
acc -10
nop -47
nop -223
jmp -155
acc +14
acc +23
jmp +23
acc +21
nop -229
acc +27
acc -5
jmp -95
acc +2
acc -10
nop -451
jmp -393
jmp -406
acc +42
acc +18
acc +49
jmp -307
acc -11
jmp +1
jmp -424
jmp -192
acc +49
acc -1
acc -17
jmp -355
jmp -268
nop -320
acc +1
jmp -134
acc +46
jmp -564
acc +40
acc +29
acc +13
nop -285
jmp -272
acc +19
acc -14
acc +25
acc +18
jmp +1