2020 Day 8 Complete!

This commit is contained in:
Brian Buller 2020-12-08 09:52:49 -06:00
parent 9d01c42165
commit 4756605dfc
5 changed files with 968 additions and 0 deletions

641
2020/day08/input Normal file
View File

@ -0,0 +1,641 @@
acc +29
acc +0
acc +36
jmp +292
acc +11
acc +16
nop +280
nop +320
jmp +310
acc +15
jmp +76
acc +31
acc +6
acc +29
acc +35
jmp +524
acc +4
acc +12
jmp +162
acc +14
acc -10
jmp +312
acc +19
jmp +385
acc +46
acc +13
acc -19
jmp +366
jmp +56
acc -9
nop +74
jmp +357
acc +28
jmp +223
acc -12
jmp +292
nop +385
acc +45
jmp +255
jmp +337
nop +465
acc +43
jmp +555
acc +20
acc +23
acc +39
jmp -6
acc -4
jmp -39
acc +7
acc -13
acc +41
acc +4
jmp +80
jmp +1
jmp +484
acc -16
acc +2
acc +20
jmp +244
jmp +258
acc +27
acc -7
acc +40
nop +490
jmp +247
nop +363
acc +46
acc +27
acc -4
jmp +379
jmp +62
acc -15
acc +38
acc -4
acc +4
jmp +312
acc +37
jmp +271
acc +3
jmp +538
jmp +1
acc +33
jmp +99
jmp +107
jmp -38
jmp +359
jmp +1
acc +11
acc -3
jmp +109
acc +17
jmp +146
acc +34
acc -5
jmp +174
jmp +482
acc +43
acc +35
acc +8
acc +36
jmp -41
jmp +260
jmp -49
acc +30
nop -33
acc +49
acc +40
jmp +157
acc -11
acc -11
acc +21
acc +35
jmp +489
jmp +219
acc +33
acc +22
jmp +224
jmp +1
jmp +278
acc +0
acc +31
jmp +271
acc -19
acc +38
acc -15
acc +0
jmp +81
acc +7
acc +50
nop +55
nop +2
jmp +195
acc -18
acc +14
jmp +1
jmp -57
acc -17
nop +495
jmp -21
jmp +1
acc +39
acc +35
acc +27
jmp +301
acc +6
acc +11
acc -10
jmp +1
jmp +56
acc +38
jmp +333
acc +26
acc -15
acc +32
acc -9
jmp +412
acc -17
acc +9
jmp +110
nop +298
acc +4
acc +25
acc +0
jmp -136
acc +24
jmp +418
acc -2
acc +38
jmp +92
acc +5
acc +22
acc -4
acc -12
jmp +241
acc +19
nop -6
acc -11
acc +24
jmp +236
jmp +106
jmp +343
jmp -17
acc +5
jmp +143
nop +354
acc +20
acc -11
jmp +63
nop +252
jmp +96
acc -11
acc +35
nop +409
acc +2
jmp +83
acc +0
acc -1
jmp +299
acc +46
jmp +426
acc +8
acc +50
acc +33
jmp +384
nop -20
jmp -152
jmp +283
nop -161
nop -76
acc +34
nop -202
jmp -98
acc +11
jmp +194
acc +12
acc +32
acc -18
acc +4
jmp +202
acc -12
acc +43
acc -11
jmp +70
acc +8
acc -5
acc +9
jmp -187
acc +49
acc +42
acc +10
jmp +274
jmp -216
acc -11
acc -8
acc +49
nop -56
jmp -197
nop -33
nop -167
jmp -174
acc +41
acc +19
acc +13
jmp +334
acc +48
acc +37
acc +35
jmp +323
jmp +1
jmp -184
nop +76
acc +47
acc +5
jmp -150
jmp +133
acc -1
jmp +197
nop +175
acc +28
jmp +328
jmp +209
nop -190
jmp +1
jmp +181
acc +33
acc +34
jmp +345
jmp -118
acc +40
acc +36
nop +32
jmp +261
acc +38
acc +1
acc -19
acc +48
jmp +320
acc +32
acc -7
acc +34
jmp +64
acc +6
acc +3
acc -11
jmp +293
acc +49
acc +23
acc +46
jmp +231
jmp +1
acc -17
jmp +35
jmp -78
jmp +82
acc +31
nop +31
acc +35
acc +42
jmp -208
acc +2
acc -16
jmp +139
nop -170
acc -4
acc +22
acc +9
jmp +295
nop -248
acc +33
acc +32
jmp +186
acc -11
jmp +151
acc +15
acc -7
acc +20
jmp -215
acc +43
acc +12
acc +6
acc +5
jmp +225
acc +15
jmp +1
nop +263
jmp -317
acc +34
jmp +1
jmp -275
acc -15
acc -12
jmp +165
nop -254
acc +12
nop +277
jmp +105
acc +35
jmp +1
acc +34
jmp +93
acc +9
jmp -282
acc +43
jmp -335
acc +21
jmp -114
acc +30
jmp -246
acc -17
acc +10
nop -211
nop +202
jmp +76
acc +34
acc +23
acc +9
acc +48
jmp -208
jmp -241
acc +37
jmp +97
acc +10
acc +47
nop -292
acc -13
jmp +27
acc -18
nop -56
jmp +33
acc +7
jmp -12
acc -11
acc -2
acc +13
jmp -328
acc +21
acc +30
jmp -208
acc -7
jmp -87
acc +41
nop +76
acc +22
jmp +222
acc +48
acc +4
jmp +225
jmp +200
acc -14
acc -12
nop -79
jmp +192
acc +41
acc +3
jmp -355
jmp -292
acc -18
jmp -174
acc +44
acc +23
jmp -163
acc +5
nop -125
nop -7
acc +41
jmp -266
jmp +90
acc +5
jmp +213
acc +10
acc -11
nop -403
jmp +1
jmp -386
acc -18
acc +9
nop +107
acc +0
jmp -383
jmp +104
acc +30
acc -3
nop -208
acc -15
jmp +211
acc -12
acc +18
jmp -392
acc +25
acc +30
jmp -170
jmp -282
acc +38
acc -16
jmp -108
acc +29
acc +31
acc +29
acc +32
jmp -258
acc -16
jmp -40
acc +41
jmp -365
acc +17
acc +20
jmp -77
jmp -55
acc +3
acc +28
nop -227
jmp +116
jmp +165
acc +16
jmp -74
acc -4
jmp -275
acc +28
jmp -254
acc +13
acc -12
acc -16
jmp -5
acc +17
nop -369
nop -375
nop +66
jmp -173
jmp -40
jmp -448
acc -10
nop -332
acc +39
acc -8
jmp +64
acc -19
acc +14
jmp -376
acc +20
acc +25
acc +11
acc +29
jmp -392
acc +33
acc +28
nop -241
acc -6
jmp +2
jmp -410
acc +15
nop -351
jmp -254
acc -2
acc +15
acc +11
jmp -103
acc +29
acc +7
jmp +21
acc +20
acc +3
acc -4
acc +31
jmp -7
acc -1
jmp +1
jmp -158
acc +11
acc -8
jmp +123
acc -9
acc +42
acc +6
acc -18
jmp -483
nop -507
acc +37
acc -10
jmp -61
jmp +98
acc +38
acc +36
jmp -358
nop -231
acc +23
acc +49
jmp -151
acc +48
acc +2
acc +19
acc +34
jmp -8
acc -14
acc -16
jmp -439
acc -7
acc -14
jmp -466
acc +1
nop -254
acc +11
jmp -72
acc +33
acc +11
acc +40
jmp -428
acc +26
acc +8
acc +19
jmp -305
nop +71
acc +3
jmp -457
acc -6
acc +36
jmp +77
acc +11
nop +68
jmp -69
acc +7
acc -8
acc +50
jmp -516
acc +11
acc +46
acc +4
jmp -179
jmp -265
nop -64
jmp +63
acc +27
nop -340
jmp -62
acc +15
acc +42
acc -9
jmp -549
acc +3
acc -10
acc +28
jmp -376
jmp +1
jmp -78
jmp -87
acc +34
acc -17
jmp -275
acc +50
acc +17
acc +39
jmp -133
nop -331
acc +33
acc +38
acc +25
jmp -215
acc +0
acc -9
jmp -258
acc +25
jmp -81
jmp -574
acc +37
acc +48
jmp -327
acc +34
nop -493
acc +42
jmp -459
jmp +1
jmp -135
jmp -489
acc +33
acc +19
acc +17
acc +7
jmp -106
nop -164
jmp -462
acc +27
jmp -612
acc +15
jmp -438
acc +35
jmp -171
acc +10
acc +4
acc +34
jmp -496
nop -4
acc +16
jmp -541
acc +13
jmp -201
jmp -551
acc +40
acc +9
acc +0
acc +33
jmp +1

60
2020/day08/main.go Normal file
View File

@ -0,0 +1,60 @@
package main
import (
"fmt"
"strings"
h "git.bullercodeworks.com/brian/adventofcode/helpers"
)
func main() {
fmt.Println("# Day 7")
inp := h.StdinToStringSlice()
FixProg(inp)
}
func RunProg(inp []string) {
var acc int
var ptr int
hist := make(map[int]int)
for ptr < len(inp) {
if _, ok := hist[ptr]; ok {
fmt.Printf("Instruction %d repeated. Acc: %d\n", ptr, acc)
return
}
hist[ptr] = acc
pts := strings.Split(inp[ptr], " ")
switch pts[0] {
case "acc":
acc = acc + h.Atoi(pts[1])
ptr++
case "jmp":
ptr = ptr + h.Atoi(pts[1])
case "nop":
ptr++
}
}
}
func FixProg(inp []string) {
p := NewProgram(inp)
chchch := p.CountOpCodes(NOP, JMP)
for ch := 1; ch <= chchch; ch++ {
np := p.Copy()
chOp := np.FindNthOp(ch, NOP, JMP)
if chOp >= 0 {
if np.Instructions[chOp].OpCode == NOP {
np.Instructions[chOp].OpCode = JMP
} else if np.Instructions[chOp].OpCode == JMP {
np.Instructions[chOp].OpCode = NOP
}
res := np.Run()
if res == 0 {
fmt.Println("Accumulator:", np.Accumulator)
return
}
}
fmt.Println("Changing", ch, "didn't fix it")
}
fmt.Println("Failed to fix program")
}

125
2020/day08/problem Normal file
View File

@ -0,0 +1,125 @@
Advent of Code
--- 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?
Your puzzle answer was 1753.
--- 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?
Your puzzle answer was 733.
Both parts of this puzzle are complete! They provide two gold stars: **
At this point, you should return to your Advent calendar and try another puzzle.
If you still want to see it, you can get your puzzle input.
References
Visible links
. https://adventofcode.com/
. https://adventofcode.com/2020/about
. https://adventofcode.com/2020/events
. https://adventofcode.com/2020/settings
. https://adventofcode.com/2020/auth/logout
. Advent of Code Supporter
https://adventofcode.com/2020/support
. https://adventofcode.com/2020
. https://adventofcode.com/2020
. https://adventofcode.com/2020/support
. https://adventofcode.com/2020/sponsors
. https://adventofcode.com/2020/leaderboard
. https://adventofcode.com/2020/stats
. https://adventofcode.com/2020/sponsors
. https://en.wikipedia.org/wiki/Handheld_game_console
. https://adventofcode.com/2020
. https://adventofcode.com/2020/day/8/input

133
2020/day08/program.go Normal file
View File

@ -0,0 +1,133 @@
package main
import (
"fmt"
"strings"
h "git.bullercodeworks.com/brian/adventofcode/helpers"
)
const (
NOP = iota
ACC
JMP
)
type Instruction struct {
OpCode int
Operand int
}
func CompileLine(inp string) Instruction {
var ret Instruction
pts := strings.Split(inp, " ")
switch pts[0] {
case "nop":
ret.OpCode = NOP
case "acc":
ret.OpCode = ACC
case "jmp":
ret.OpCode = JMP
}
ret.Operand = h.Atoi(pts[1])
return ret
}
type Program struct {
Pointer int
Accumulator int
Instructions []Instruction
Code []string
History map[int]int
BreakOnLoop bool
Verbose bool
}
func NewProgram(inp []string) *Program {
p := &Program{
Pointer: 0,
Accumulator: 0,
Code: inp,
History: make(map[int]int),
BreakOnLoop: true,
Verbose: true,
}
p.Compile()
return p
}
func (p *Program) Copy() *Program {
cp := Program{
Pointer: p.Pointer,
Accumulator: p.Accumulator,
Code: p.Code,
History: make(map[int]int),
BreakOnLoop: p.BreakOnLoop,
Verbose: p.Verbose,
}
for k, v := range p.History {
cp.History[k] = v
}
cp.Compile()
return &cp
}
func (p *Program) Compile() {
for k := range p.Code {
p.Instructions = append(p.Instructions, CompileLine(p.Code[k]))
}
}
func (p *Program) Run() int {
for p.Pointer < len(p.Instructions) {
if p.BreakOnLoop {
if _, ok := p.History[p.Pointer]; ok {
if p.Verbose {
fmt.Printf("Instruction %d repeated. Acc: %d\n", p.Pointer, p.Accumulator)
}
return 1
}
}
p.History[p.Pointer] = p.Accumulator
switch p.Instructions[p.Pointer].OpCode {
case NOP:
p.Pointer++
case ACC:
p.Accumulator = p.Accumulator + p.Instructions[p.Pointer].Operand
p.Pointer++
case JMP:
p.Pointer = p.Pointer + p.Instructions[p.Pointer].Operand
}
}
if p.Verbose {
fmt.Println("Done")
}
return 0
}
func (p *Program) CountOpCodes(tp ...int) int {
var ret int
for tpk := range tp {
for k := range p.Instructions {
if p.Instructions[k].OpCode == tp[tpk] {
ret++
}
}
}
return ret
}
func (p *Program) FindNthOp(n int, tp ...int) int {
for i := 0; i < len(p.Instructions); i++ {
for _, tpv := range tp {
if p.Instructions[i].OpCode == tpv {
n--
}
if n == 0 {
return i
}
}
}
return -1
}

9
2020/day08/testinput Normal file
View File

@ -0,0 +1,9 @@
nop +0
acc +1
jmp +4
acc +3
jmp -3
acc -99
acc +1
jmp -4
acc +6