might be making a mistake starting 2018...

This commit is contained in:
alexchao26
2020-09-06 20:12:08 -04:00
parent 6508ec81d4
commit 3aa2b3e09a
104 changed files with 1100 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
1102,34463338,34463338,63,1007,63,34463338,63,1005,63,53,1101,3,0,1000,109,988,209,12,9,1000,209,6,209,3,203,0,1008,1000,1,63,1005,63,65,1008,1000,2,63,1005,63,904,1008,1000,0,63,1005,63,58,4,25,104,0,99,4,0,104,0,99,4,17,104,0,99,0,0,1101,27,0,1014,1101,286,0,1023,1102,1,35,1018,1102,20,1,1000,1101,26,0,1010,1101,0,289,1022,1102,1,30,1019,1102,734,1,1025,1102,1,31,1012,1101,25,0,1001,1102,1,1,1021,1101,0,36,1002,1101,0,527,1028,1101,895,0,1026,1102,1,23,1016,1101,21,0,1003,1102,22,1,1011,1102,1,522,1029,1102,1,892,1027,1102,1,0,1020,1102,1,28,1015,1102,38,1,1006,1101,0,32,1008,1101,743,0,1024,1101,0,37,1007,1102,1,24,1013,1102,1,33,1009,1102,39,1,1004,1102,1,34,1005,1102,1,29,1017,109,19,21102,40,1,-3,1008,1016,40,63,1005,63,203,4,187,1106,0,207,1001,64,1,64,1002,64,2,64,109,-7,2101,0,-7,63,1008,63,32,63,1005,63,227,1106,0,233,4,213,1001,64,1,64,1002,64,2,64,109,-3,2108,37,-2,63,1005,63,255,4,239,1001,64,1,64,1105,1,255,1002,64,2,64,109,11,21108,41,40,-6,1005,1014,275,1001,64,1,64,1106,0,277,4,261,1002,64,2,64,109,10,2105,1,-7,1105,1,295,4,283,1001,64,1,64,1002,64,2,64,109,-27,1201,-2,0,63,1008,63,25,63,1005,63,321,4,301,1001,64,1,64,1105,1,321,1002,64,2,64,109,15,21107,42,41,0,1005,1018,341,1001,64,1,64,1106,0,343,4,327,1002,64,2,64,109,-25,2108,20,10,63,1005,63,359,1105,1,365,4,349,1001,64,1,64,1002,64,2,64,109,12,2107,35,0,63,1005,63,385,1001,64,1,64,1106,0,387,4,371,1002,64,2,64,109,4,21101,43,0,6,1008,1015,43,63,1005,63,409,4,393,1106,0,413,1001,64,1,64,1002,64,2,64,109,9,21101,44,0,-8,1008,1010,46,63,1005,63,437,1001,64,1,64,1106,0,439,4,419,1002,64,2,64,109,5,21108,45,45,-4,1005,1019,457,4,445,1106,0,461,1001,64,1,64,1002,64,2,64,109,-22,2102,1,7,63,1008,63,33,63,1005,63,481,1106,0,487,4,467,1001,64,1,64,1002,64,2,64,109,14,21102,46,1,-1,1008,1014,43,63,1005,63,507,1106,0,513,4,493,1001,64,1,64,1002,64,2,64,109,12,2106,0,1,4,519,1106,0,531,1001,64,1,64,1002,64,2,64,109,-17,1205,10,547,1001,64,1,64,1106,0,549,4,537,1002,64,2,64,109,-8,1202,-2,1,63,1008,63,17,63,1005,63,569,1105,1,575,4,555,1001,64,1,64,1002,64,2,64,109,23,1206,-5,593,4,581,1001,64,1,64,1105,1,593,1002,64,2,64,109,-14,1208,-8,24,63,1005,63,613,1001,64,1,64,1105,1,615,4,599,1002,64,2,64,109,-2,1207,-1,33,63,1005,63,633,4,621,1105,1,637,1001,64,1,64,1002,64,2,64,109,2,21107,47,48,5,1005,1016,659,4,643,1001,64,1,64,1105,1,659,1002,64,2,64,109,-11,1208,8,32,63,1005,63,681,4,665,1001,64,1,64,1106,0,681,1002,64,2,64,109,2,2101,0,0,63,1008,63,36,63,1005,63,703,4,687,1106,0,707,1001,64,1,64,1002,64,2,64,109,12,1206,7,719,1106,0,725,4,713,1001,64,1,64,1002,64,2,64,109,2,2105,1,8,4,731,1001,64,1,64,1106,0,743,1002,64,2,64,109,-21,2102,1,9,63,1008,63,39,63,1005,63,769,4,749,1001,64,1,64,1105,1,769,1002,64,2,64,109,11,1201,-3,0,63,1008,63,24,63,1005,63,793,1001,64,1,64,1105,1,795,4,775,1002,64,2,64,109,20,1205,-5,809,4,801,1105,1,813,1001,64,1,64,1002,64,2,64,109,-23,1207,4,36,63,1005,63,833,1001,64,1,64,1105,1,835,4,819,1002,64,2,64,109,-3,2107,33,5,63,1005,63,853,4,841,1106,0,857,1001,64,1,64,1002,64,2,64,109,16,1202,-9,1,63,1008,63,37,63,1005,63,879,4,863,1105,1,883,1001,64,1,64,1002,64,2,64,109,12,2106,0,-1,1105,1,901,4,889,1001,64,1,64,4,64,99,21101,0,27,1,21101,0,915,0,1106,0,922,21201,1,48476,1,204,1,99,109,3,1207,-2,3,63,1005,63,964,21201,-2,-1,1,21101,0,942,0,1105,1,922,21202,1,1,-1,21201,-2,-3,1,21101,0,957,0,1105,1,922,22201,1,-1,-2,1106,0,968,21202,-2,1,-2,109,-3,2106,0,0
+210
View File
@@ -0,0 +1,210 @@
/*
Intcode struct is defined within this file
MakePermutations is in the util package as that will likely be reused
*/
package main
import (
"adventofcode/util"
"fmt"
"log"
"strconv"
"strings"
)
func main() {
// read the input file, modify it to a slice of numbers
inputFile := util.ReadFile("../input.txt")
splitStrings := strings.Split(inputFile, ",")
inputNumbers := make([]int, len(splitStrings))
for i, v := range splitStrings {
inputNumbers[i], _ = strconv.Atoi(v)
}
// initialize a computer with a test mode input of `1`
comp := MakeComputer(inputNumbers, 1)
fmt.Println("BOOST keycode is", comp.LastOutput)
}
/*
Intcode is an OOP approach *************************************************
MakeComputer is equivalent to the constructor
Step takes in an input int and updates properties in the computer:
- InstructionIndex: where to read the next instruction from
- LastOutput, what the last opcode 4 outputted
- PuzzleIndex based if the last instruction modified the puzzle at all
****************************************************************************/
type Intcode struct {
PhaseSetting int // initial input: ID or number used to "prime"/setup the comp
PuzzleInput []int // file/puzzle input parsed into slice of ints
InstructionIndex int // stores the index where the next instruction is
RelativeBase int // relative base for opcode 9 and param mode 2
LastOutput int // last output from an opcode 4
IsRunning bool // will be true until a 99 opcode is hit
}
// MakeComputer initializes a new comp
func MakeComputer(PuzzleInput []int, PhaseSetting int) Intcode {
puzzleInputCopy := make([]int, len(PuzzleInput))
copy(puzzleInputCopy, PuzzleInput)
comp := Intcode{
PhaseSetting,
puzzleInputCopy,
0,
0,
0,
true,
}
// Prime the computer by running its initial phase setting through it
// This will update the comp's InstructionIndex so it's pointing to the next command
// will also update the PuzzleInput itself via opcode 3's insert
// AND will run the computer until it asks for the next input, _comp is now primed_
comp.Step(PhaseSetting)
return comp
}
// Step will read the next 4 values in the input `sli` and make updates
// according to the opcodes
func (comp *Intcode) Step(input int) {
// read the instruction, opcode and the indexes where the params point to
opcode, paramIndexes := comp.GetOpCodeAndParamIndexes()
param1, param2, param3 := paramIndexes[0], paramIndexes[1], paramIndexes[2]
// ensure params are within the bounds of PuzzleInput, resize if necessary
comp.ResizeMemory(param1, param2, param3)
switch opcode {
case 99: // 99: Terminates program
// fmt.Println("Terminating...")
comp.IsRunning = false
case 1: // 1: Add next two paramIndexes, store in third
comp.PuzzleInput[param3] = comp.PuzzleInput[param1] + comp.PuzzleInput[param2]
comp.InstructionIndex += 4
comp.Step(input)
case 2: // 2: Multiply next two and store in third
comp.PuzzleInput[param3] = comp.PuzzleInput[param1] * comp.PuzzleInput[param2]
comp.InstructionIndex += 4
comp.Step(input)
case 3: // 3: Takes one input and saves it to position of one parameter
// check if input has already been used (i.e. input == -1)
// if it's been used, return out to prevent further Steps
// NOTE: making a big assumption that -1 will never be an input...
if input == -1 {
return
}
// else recurse with a -1 to signal the initial input has been processed
comp.PuzzleInput[param1] = input
comp.InstructionIndex += 2
comp.Step(-1)
case 4: // 4: outputs its input value
// set LastOutput of the computer & log it
comp.LastOutput = comp.PuzzleInput[param1]
// fmt.Printf("Opcode 4 output: %v\n", comp.LastOutput)
comp.InstructionIndex += 2
// continue running until terminates or asks for another input
comp.Step(input)
// 5: jump-if-true: if first param != 0, move pointer to second param, else nothing
case 5:
if comp.PuzzleInput[param1] != 0 {
comp.InstructionIndex = comp.PuzzleInput[param2]
} else {
comp.InstructionIndex += 3
}
comp.Step(input)
// 6: jump-if-false, if first param == 0 then set instruction pointer to 2nd param, else nothing
case 6:
if comp.PuzzleInput[param1] == 0 {
comp.InstructionIndex = comp.PuzzleInput[param2]
} else {
comp.InstructionIndex += 3
}
comp.Step(input)
// 7: less-than, if param1 < param2 then store 1 in postion of 3rd param, else store 0
case 7:
if comp.PuzzleInput[param1] < comp.PuzzleInput[param2] {
comp.PuzzleInput[param3] = 1
} else {
comp.PuzzleInput[param3] = 0
}
comp.InstructionIndex += 4
comp.Step(input)
// 8: equals, if param1 == param2 then set position of 3rd param to 1, else store 0
case 8:
if comp.PuzzleInput[param1] == comp.PuzzleInput[param2] {
comp.PuzzleInput[param3] = 1
} else {
comp.PuzzleInput[param3] = 0
}
comp.InstructionIndex += 4
comp.Step(input)
// 9: adjust relative base
case 9:
comp.RelativeBase += comp.PuzzleInput[param1]
comp.InstructionIndex += 2
comp.Step(input)
default:
log.Fatalf("Error: unknown opcode %v at index %v", opcode, comp.PuzzleInput[comp.InstructionIndex])
}
}
/*
GetOpCodeAndParamIndexes will parse the instruction at comp.PuzzleInput[comp.InstructionIndex]
- opcode will be the left two digits, mod by 100 will get that
- rest of instructions will be grabbed via mod 10
- these also have to be parsed for the
*/
func (comp *Intcode) GetOpCodeAndParamIndexes() (int, [3]int) {
instruction := comp.PuzzleInput[comp.InstructionIndex]
// opcode is the lowest two digits, so mod by 100
opcode := instruction % 100
instruction /= 100
// assign the indexes that need to be read by reading the parameter modes
var paramIndexes [3]int
for i := 1; i <= 3 && comp.InstructionIndex+i < len(comp.PuzzleInput); i++ {
// grab the mode with a mod, last digit
mode := instruction % 10
instruction /= 10
switch mode {
case 0: // position mode, index will be the value at the index
paramIndexes[i-1] = comp.PuzzleInput[comp.InstructionIndex+i]
case 1: // immediate mode, the index itself
paramIndexes[i-1] = comp.InstructionIndex + i
case 2: // relative mode, like position mode but index is added to relative base
paramIndexes[i-1] = comp.PuzzleInput[comp.InstructionIndex+i] + comp.RelativeBase
}
}
return opcode, paramIndexes
}
// ResizeMemory will take any number of integers and resize the computer's memory appropriately
func (comp *Intcode) ResizeMemory(sizes ...int) {
// get largest of input sizes
maxArgSize := sizes[0]
for _, v := range sizes {
if v > maxArgSize {
maxArgSize = v
}
}
// resize if PuzzleInput's length is shorter
if maxArgSize > len(comp.PuzzleInput) {
// make empty slice to copy into, of the new, larger size
resizedPuzzleInput := make([]int, maxArgSize)
// copy old puzzle input values in
copy(resizedPuzzleInput, comp.PuzzleInput)
// overwrite puzzle input
comp.PuzzleInput = resizedPuzzleInput
}
}
+210
View File
@@ -0,0 +1,210 @@
/*
Intcode struct is defined within this file
MakePermutations is in the util package as that will likely be reused
*/
package main
import (
"adventofcode/util"
"fmt"
"log"
"strconv"
"strings"
)
func main() {
// read the input file, modify it to a slice of numbers
inputFile := util.ReadFile("../input.txt")
splitStrings := strings.Split(inputFile, ",")
inputNumbers := make([]int, len(splitStrings))
for i, v := range splitStrings {
inputNumbers[i], _ = strconv.Atoi(v)
}
// initialize a computer with a senor boost input of `2`
comp := MakeComputer(inputNumbers, 2)
fmt.Println("BOOST keycode is", comp.LastOutput)
}
/*
Intcode is an OOP approach *************************************************
MakeComputer is equivalent to the constructor
Step takes in an input int and updates properties in the computer:
- InstructionIndex: where to read the next instruction from
- LastOutput, what the last opcode 4 outputted
- PuzzleIndex based if the last instruction modified the puzzle at all
****************************************************************************/
type Intcode struct {
PhaseSetting int // initial input: ID or number used to "prime"/setup the comp
PuzzleInput []int // file/puzzle input parsed into slice of ints
InstructionIndex int // stores the index where the next instruction is
RelativeBase int // relative base for opcode 9 and param mode 2
LastOutput int // last output from an opcode 4
IsRunning bool // will be true until a 99 opcode is hit
}
// MakeComputer initializes a new comp
func MakeComputer(PuzzleInput []int, PhaseSetting int) Intcode {
puzzleInputCopy := make([]int, len(PuzzleInput))
copy(puzzleInputCopy, PuzzleInput)
comp := Intcode{
PhaseSetting,
puzzleInputCopy,
0,
0,
0,
true,
}
// Prime the computer by running its initial phase setting through it
// This will update the comp's InstructionIndex so it's pointing to the next command
// will also update the PuzzleInput itself via opcode 3's insert
// AND will run the computer until it asks for the next input, _comp is now primed_
comp.Step(PhaseSetting)
return comp
}
// Step will read the next 4 values in the input `sli` and make updates
// according to the opcodes
func (comp *Intcode) Step(input int) {
// read the instruction, opcode and the indexes where the params point to
opcode, paramIndexes := comp.GetOpCodeAndParamIndexes()
param1, param2, param3 := paramIndexes[0], paramIndexes[1], paramIndexes[2]
// ensure params are within the bounds of PuzzleInput, resize if necessary
comp.ResizeMemory(param1, param2, param3)
switch opcode {
case 99: // 99: Terminates program
// fmt.Println("Terminating...")
comp.IsRunning = false
case 1: // 1: Add next two paramIndexes, store in third
comp.PuzzleInput[param3] = comp.PuzzleInput[param1] + comp.PuzzleInput[param2]
comp.InstructionIndex += 4
comp.Step(input)
case 2: // 2: Multiply next two and store in third
comp.PuzzleInput[param3] = comp.PuzzleInput[param1] * comp.PuzzleInput[param2]
comp.InstructionIndex += 4
comp.Step(input)
case 3: // 3: Takes one input and saves it to position of one parameter
// check if input has already been used (i.e. input == -1)
// if it's been used, return out to prevent further Steps
// NOTE: making a big assumption that -1 will never be an input...
if input == -1 {
return
}
// else recurse with a -1 to signal the initial input has been processed
comp.PuzzleInput[param1] = input
comp.InstructionIndex += 2
comp.Step(-1)
case 4: // 4: outputs its input value
// set LastOutput of the computer & log it
comp.LastOutput = comp.PuzzleInput[param1]
// fmt.Printf("Opcode 4 output: %v\n", comp.LastOutput)
comp.InstructionIndex += 2
// continue running until terminates or asks for another input
comp.Step(input)
// 5: jump-if-true: if first param != 0, move pointer to second param, else nothing
case 5:
if comp.PuzzleInput[param1] != 0 {
comp.InstructionIndex = comp.PuzzleInput[param2]
} else {
comp.InstructionIndex += 3
}
comp.Step(input)
// 6: jump-if-false, if first param == 0 then set instruction pointer to 2nd param, else nothing
case 6:
if comp.PuzzleInput[param1] == 0 {
comp.InstructionIndex = comp.PuzzleInput[param2]
} else {
comp.InstructionIndex += 3
}
comp.Step(input)
// 7: less-than, if param1 < param2 then store 1 in postion of 3rd param, else store 0
case 7:
if comp.PuzzleInput[param1] < comp.PuzzleInput[param2] {
comp.PuzzleInput[param3] = 1
} else {
comp.PuzzleInput[param3] = 0
}
comp.InstructionIndex += 4
comp.Step(input)
// 8: equals, if param1 == param2 then set position of 3rd param to 1, else store 0
case 8:
if comp.PuzzleInput[param1] == comp.PuzzleInput[param2] {
comp.PuzzleInput[param3] = 1
} else {
comp.PuzzleInput[param3] = 0
}
comp.InstructionIndex += 4
comp.Step(input)
// 9: adjust relative base
case 9:
comp.RelativeBase += comp.PuzzleInput[param1]
comp.InstructionIndex += 2
comp.Step(input)
default:
log.Fatalf("Error: unknown opcode %v at index %v", opcode, comp.PuzzleInput[comp.InstructionIndex])
}
}
/*
GetOpCodeAndParamIndexes will parse the instruction at comp.PuzzleInput[comp.InstructionIndex]
- opcode will be the left two digits, mod by 100 will get that
- rest of instructions will be grabbed via mod 10
- these also have to be parsed for the
*/
func (comp *Intcode) GetOpCodeAndParamIndexes() (int, [3]int) {
instruction := comp.PuzzleInput[comp.InstructionIndex]
// opcode is the lowest two digits, so mod by 100
opcode := instruction % 100
instruction /= 100
// assign the indexes that need to be read by reading the parameter modes
var paramIndexes [3]int
for i := 1; i <= 3 && comp.InstructionIndex+i < len(comp.PuzzleInput); i++ {
// grab the mode with a mod, last digit
mode := instruction % 10
instruction /= 10
switch mode {
case 0: // position mode, index will be the value at the index
paramIndexes[i-1] = comp.PuzzleInput[comp.InstructionIndex+i]
case 1: // immediate mode, the index itself
paramIndexes[i-1] = comp.InstructionIndex + i
case 2: // relative mode, like position mode but index is added to relative base
paramIndexes[i-1] = comp.PuzzleInput[comp.InstructionIndex+i] + comp.RelativeBase
}
}
return opcode, paramIndexes
}
// ResizeMemory will take any number of integers and resize the computer's memory appropriately
func (comp *Intcode) ResizeMemory(sizes ...int) {
// get largest of input sizes
maxArgSize := sizes[0]
for _, v := range sizes {
if v > maxArgSize {
maxArgSize = v
}
}
// resize if PuzzleInput's length is shorter
if maxArgSize > len(comp.PuzzleInput) {
// make empty slice to copy into, of the new, larger size
resizedPuzzleInput := make([]int, maxArgSize)
// copy old puzzle input values in
copy(resizedPuzzleInput, comp.PuzzleInput)
// overwrite puzzle input
comp.PuzzleInput = resizedPuzzleInput
}
}