day07 refactor before starting day09

This commit is contained in:
Alex Chao
2020-08-03 17:22:40 -04:00
parent 6144750bd7
commit 3832f22775
2 changed files with 38 additions and 40 deletions
+3 -2
View File
@@ -12,5 +12,6 @@ Day | Name | Type of Algo & Notes
4 | Secure Container | - May appear math-y, but it's really a string manipulation problem
5 | Sunny with a Chance of Asteroids | - Yay more Intcode!........ <br> - This gave me fits... <br> - Good application for recursion (in my opinion)
6 | Universal Orbit Map | - __Tree traversal__ and depth calculations. It's not quite a Graph, but it has a __directed graph__ algo feel too
7 | Amplification Circuit | - More Intcode... Piping together multiple Intcode computers 😳😳😳 <br> - Refactored Intcode computer to an OOP approach so a single computer maintains its data <br> - Also requires making __permutations generator__ <br> - Some gymnastics to make this circular, but its easier with this OOP approach and the "objects"/instances of a struct maintaining their own data
8 | Space Image Format | 3D Array manipulation
7 | Amplification Circuit | - More Intcode... Piping together multiple Intcode computers 😳😳😳 <br> - Refactored Intcode computer to an OOP approach so a single computer maintains its data <br> - Also requires making __permutations generator__ <br> - Some gymnastics to make this circular, but its easier with this OOP approach and the "objects"/instances of a struct maintaining their own data <br> - Concurrency could be used to sync these Amps together...
8 | Space Image Format | 3D Array manipulation, pretty straight forward
9 | Sensor Boost | __MORE INTCODE. YAYY__ 🙃 <br> - A new parameter mode and opcode. <br> - __Really feeling the (tech) debt of some earlier design choices here, went back to refactor day07 before jumping into this one__
+35 -38
View File
@@ -21,10 +21,9 @@ func main() {
inputNumbers := make([]int, len(splitStrings))
for i, v := range splitStrings {
fmt.Println(v)
inputNumbers[i], _ = strconv.Atoi(v)
}
fmt.Println(inputNumbers)
// Make perms via a util function
perms := util.MakePermutations([]int{5, 6, 7, 8, 9})
@@ -97,91 +96,89 @@ func MakeComputer(PuzzleInput []int, PhaseSetting int) Intcode {
// Step will read the next 4 values in the input `sli` and make updates
// according to the opcodes
func (comp *Intcode) Step(input int) int {
func (comp *Intcode) Step(input int) {
// read the instruction, opcode and the indexes where the params point to
opcode, paramIndexes := comp.GetOpCodeAndIndexes()
opcode, paramIndexes := comp.GetOpCodeAndParamIndexes()
param1, param2, param3 := paramIndexes[0], paramIndexes[1], paramIndexes[2]
switch opcode {
case 99: // 99: Terminates program
fmt.Println("Terminating...")
// fmt.Println("Terminating...")
comp.IsRunning = false
return input
case 1: // 1: Add next two paramIndexes, store in third
comp.PuzzleInput[paramIndexes[2]] = comp.PuzzleInput[paramIndexes[0]] + comp.PuzzleInput[paramIndexes[1]]
comp.PuzzleInput[param3] = comp.PuzzleInput[param1] + comp.PuzzleInput[param2]
comp.InstructionIndex += 4
return comp.Step(input)
comp.Step(input)
case 2: // 2: Multiply next two and store in third
comp.PuzzleInput[paramIndexes[2]] = comp.PuzzleInput[paramIndexes[0]] * comp.PuzzleInput[paramIndexes[1]]
comp.PuzzleInput[param3] = comp.PuzzleInput[param1] * comp.PuzzleInput[param2]
comp.InstructionIndex += 4
return comp.Step(input)
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 the LastOutput
// 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 comp.LastOutput
return
}
// otherwise use the input, then recurse with a -1 to signal the initial input has been used
comp.PuzzleInput[paramIndexes[0]] = input
// else recurse with a -1 to signal the initial input has been processed
comp.PuzzleInput[param1] = input
comp.InstructionIndex += 2
return comp.Step(-1)
comp.Step(-1)
case 4: // 4: outputs its input value
// set LastOutput of the computer & log it
comp.LastOutput = comp.PuzzleInput[paramIndexes[0]]
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
return comp.Step(input)
comp.Step(input)
// 5: jump-if-true: if first param != 0, move pointer to second param, else nothing
case 5:
if comp.PuzzleInput[paramIndexes[0]] != 0 {
comp.InstructionIndex = comp.PuzzleInput[paramIndexes[1]]
if comp.PuzzleInput[param1] != 0 {
comp.InstructionIndex = comp.PuzzleInput[param2]
} else {
comp.InstructionIndex += 3
}
return comp.Step(input)
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[paramIndexes[0]] == 0 {
comp.InstructionIndex = comp.PuzzleInput[paramIndexes[1]]
if comp.PuzzleInput[param1] == 0 {
comp.InstructionIndex = comp.PuzzleInput[param2]
} else {
comp.InstructionIndex += 3
}
return comp.Step(input)
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[paramIndexes[0]] < comp.PuzzleInput[paramIndexes[1]] {
comp.PuzzleInput[paramIndexes[2]] = 1
if comp.PuzzleInput[param1] < comp.PuzzleInput[param2] {
comp.PuzzleInput[param3] = 1
} else {
comp.PuzzleInput[paramIndexes[2]] = 0
comp.PuzzleInput[param3] = 0
}
comp.InstructionIndex += 4
return comp.Step(input)
comp.Step(input)
// 8: equals, if param1 == param2 then set position of 3rd param to 1, else store 0
case 8:
if comp.PuzzleInput[paramIndexes[0]] == comp.PuzzleInput[paramIndexes[1]] {
comp.PuzzleInput[paramIndexes[2]] = 1
if comp.PuzzleInput[param1] == comp.PuzzleInput[param2] {
comp.PuzzleInput[param3] = 1
} else {
comp.PuzzleInput[paramIndexes[2]] = 0
comp.PuzzleInput[param3] = 0
}
comp.InstructionIndex += 4
return comp.Step(input)
comp.Step(input)
default:
log.Fatal("Error: unknown opcode: ", opcode)
log.Fatalf("Error: unknown opcode %v at index %v", opcode, comp.PuzzleInput[comp.InstructionIndex])
}
// this should never be called b/c switch statement will always return
return -1
}
/*
GetOpCodeAndIndexes will parse the instruction at 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) GetOpCodeAndIndexes() (int, [3]int) {
func (comp *Intcode) GetOpCodeAndParamIndexes() (int, [3]int) {
instruction := comp.PuzzleInput[comp.InstructionIndex]
// opcode is the lowest two digits, so mod by 100
@@ -196,10 +193,10 @@ func (comp *Intcode) GetOpCodeAndIndexes() (int, [3]int) {
instruction /= 10
switch mode {
case 1: // immediate mode, the index itself
paramIndexes[i-1] = comp.InstructionIndex + i
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
}
}