day 8 done

This commit is contained in:
David 2020-12-08 18:48:21 -05:00
parent dd8eb8c1f8
commit 6925fabb63
2 changed files with 756 additions and 0 deletions

591
08/input Normal file
View File

@ -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

165
08/main.go Normal file
View File

@ -0,0 +1,165 @@
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
partOne()
partTwo()
}
type opCode struct {
operation string
value int
}
type register struct {
value int
}
type registry map[string]*register
type program []opCode
func lineToOp(s string) opCode {
sp := strings.Split(s, " ")
i, _ := strconv.Atoi(sp[1])
return opCode{
operation: sp[0],
value: i,
}
}
// take registry, program, current opcode location, perform operation if possible, return next opcode location
func execute(r registry, p program, i int) (int, error) {
if i >= len(p) {
return -1, fmt.Errorf("program terminates")
}
currentOp := p[i]
switch currentOp.operation {
case "nop":
return i + 1, nil
case "acc":
r["acc"].value = r["acc"].value + currentOp.value
return i + 1, nil
case "jmp":
return i + currentOp.value, nil
default:
return -1, fmt.Errorf("unknown opcode")
}
}
// 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.
// Run your copy of the boot code. Immediately before any instruction is executed a second time, what value is in the accumulator?
func partOne() {
f, _ := os.Open("input")
reader := bufio.NewReader(f)
scanner := bufio.NewScanner(reader)
prog := program{}
for scanner.Scan() {
line := scanner.Text()
prog = append(prog, lineToOp(line))
}
reg := registry{
"acc": &register{
value: 0,
},
}
currentOp := 0
executedLines := []int{}
for {
executedLines = append(executedLines, currentOp)
nextOp, err := execute(reg, prog, currentOp)
if nextOp == -1 || err != nil {
fmt.Println(err.Error())
break
}
for _, j := range executedLines {
if nextOp == j {
fmt.Println(reg["acc"].value)
return
}
}
currentOp = nextOp
}
}
// 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.
// 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?
func partTwo() {
f, _ := os.Open("input")
reader := bufio.NewReader(f)
scanner := bufio.NewScanner(reader)
prog := program{}
for scanner.Scan() {
line := scanner.Text()
prog = append(prog, lineToOp(line))
}
// guess we're just going to brute-force this huh
for i := range prog {
newP := make(program, len(prog))
copy(newP, prog)
if prog[i].operation == "jmp" {
newP[i].operation = "nop"
} else if prog[i].operation == "nop" {
newP[i].operation = "jmp"
}
result, err := isolatedProgramRunner(newP)
if err == nil {
fmt.Println(result)
return
}
}
}
func isolatedProgramRunner(p program) (int, error) {
reg := registry{
"acc": &register{
value: 0,
},
}
executedLines := []int{}
currentOp := 0
for {
executedLines = append(executedLines, currentOp)
nextOp, err := execute(reg, p, currentOp)
if nextOp == -1 {
return reg["acc"].value, nil
}
if err != nil {
return -1, err
}
for _, j := range executedLines {
if nextOp == j {
return -1, fmt.Errorf("program loops")
}
}
currentOp = nextOp
}
}