M .gitignore => .gitignore +3 -1
@@ 3,4 3,6 @@
# Unignore all with extensions
!*.*
# Unignore all dirs
-!*/>
\ No newline at end of file
+!*/
+
+.idea/<
\ No newline at end of file
M cmd/day2/main.go => cmd/day2/main.go +11 -31
@@ 1,6 1,9 @@
package main
-import "fmt"
+import (
+ "fmt"
+ computer "git.sr.ht/~zacbrown/aoc-2019-go"
+)
var intCodeProgram = []int{
1, 0, 0, 3, 1, 1, 2, 3, 1, 3, 4, 3, 1, 5, 0, 3, 2, 13, 1, 19,
@@ 12,52 15,29 @@ var intCodeProgram = []int{
107, 6, 111, 1, 111, 2, 115, 1, 115, 13, 0, 99, 2, 0, 14, 0,
}
-func eval(program []int) []int {
- pc := program[:]
- for {
- // Perform whatever operation we're going to.
- switch pc[0] {
- case 1:
- inPos1 := pc[1]
- inPos2 := pc[2]
- outPos := pc[3]
- program[outPos] = program[inPos1] + program[inPos2]
- pc = pc[4:]
- case 2:
- inPos1 := pc[1]
- inPos2 := pc[2]
- outPos := pc[3]
- program[outPos] = program[inPos1] * program[inPos2]
- pc = pc[4:]
- case 99:
- return program
- }
- }
-}
-
func main() {
fmt.Println("============= PART 1 =============")
programCopy := make([]int, len(intCodeProgram))
copy(programCopy, intCodeProgram)
programCopy[1] = 12
programCopy[2] = 2
- result := eval(programCopy)
- fmt.Println("Program result: ", result[0])
+ c := computer.NewComputer(programCopy)
+ c.Eval(nil)
+ fmt.Println("Program result: ", programCopy[0])
// Part 2
- const targetValue int = 19690720
fmt.Println("\n============= PART 2 =============")
+ const targetValue int = 19690720
out:
for ii := 0; ii < 99; ii++ {
for jj := 0; jj < 99; jj++ {
- fmt.Printf("Trying noun=%d, verb=%d.\n", ii, jj)
-
copy(programCopy, intCodeProgram)
programCopy[1] = ii
programCopy[2] = jj
- output := eval(programCopy)
+ c := computer.NewComputer(programCopy)
+ c.Eval(nil)
- if output[0] == targetValue {
+ if programCopy[0] == targetValue {
fmt.Printf("Match found: noun=%d, verb=%d.\n", ii, jj)
fmt.Printf("Solution: 100 * %d + %d = %d\n", ii, jj, (100*ii)+jj)
break out
M cmd/day5/main.go => cmd/day5/main.go +19 -216
@@ 1,11 1,8 @@
package main
import (
- "bufio"
"fmt"
- "os"
- "strconv"
- "strings"
+ computer "git.sr.ht/~zacbrown/aoc-2019-go"
)
var intCodeProgram = []int{
@@ 46,222 43,28 @@ var intCodeProgram = []int{
1001, 223, 1, 223, 4, 223, 99, 226,
}
-var reader *bufio.Reader
-const (
- positionMode = 0
- immediateMode = 1
-)
-
-func eval(program []int) []int {
- pc := program[:]
+func main() {
+ fmt.Println("============= PART 1 =============")
+ programCopy := make([]int, len(intCodeProgram))
+ copy(programCopy, intCodeProgram)
+ c := computer.NewComputer(programCopy)
+ input := []int{1}
for {
- // If the instruction is 1002, we want the least two digits - the tens
- // and the ones position. To get this, we modulo by 100: 1002 % 100 = 02
- instr := pc[0] % 100
- // Perform whatever operation we're going to.
- switch instr {
- case 1:
- // Add
- in1 := pc[1]
- in1Mode := (pc[0] / 100) % 10
- in2 := pc[2]
- in2Mode := (pc[0] / 1000) % 10
- out := pc[3]
-
- var in1Value int
- if in1Mode == positionMode {
- in1Value = program[in1]
- } else {
- in1Value = in1
- }
-
- var in2Value int
- if in2Mode == positionMode {
- in2Value = program[in2]
- } else {
- in2Value = in2
- }
-
- program[out] = in1Value + in2Value
- pc = pc[4:]
- case 2:
- // Multiply
- in1 := pc[1]
- in1Mode := (pc[0] / 100) % 10
- in2 := pc[2]
- in2Mode := (pc[0] / 1000) % 10
- out := pc[3]
-
- var in1Value int
- if in1Mode == positionMode {
- in1Value = program[in1]
- } else {
- in1Value = in1
- }
-
- var in2Value int
- if in2Mode == positionMode {
- in2Value = program[in2]
- } else {
- in2Value = in2
- }
-
- program[out] = in1Value * in2Value
- pc = pc[4:]
- case 3:
- // Input
- print("input requested: ")
- inPos := pc[1]
- input, _ := reader.ReadString('\n')
- input = strings.Trim(input, " \n\t")
-
- inputAsInt, err := strconv.Atoi(input)
- if err != nil {
- panic(fmt.Sprintf("Non-integer input provided: %s. Err: %v", input, err))
- }
-
- program[inPos] = inputAsInt
- pc = pc[2:]
- case 4:
- // Output
- outPos := pc[1]
- outMode := (pc[0] / 100) % 10
-
- if outMode == positionMode {
- println(program[outPos])
- } else {
- println(outPos)
- }
- pc = pc[2:]
- case 5:
- // jump-if-true
- in1 := pc[1]
- in1Mode := (pc[0] / 100) % 10
-
- in2 := pc[2]
- in2Mode := (pc[0] / 1000) % 10
-
- var numToEval int
- if in1Mode == positionMode {
- numToEval = program[in1]
- } else {
- numToEval = in1
- }
-
- var targetPosition int
- if in2Mode == positionMode {
- targetPosition = program[in2]
- } else {
- targetPosition = in2
- }
-
- // Jump if it's non-zero.
- if numToEval != 0 {
- pc = program[targetPosition:]
- } else {
- pc = pc[3:]
- }
- case 6:
- // jump-if-false
- in1 := pc[1]
- in1Mode := (pc[0] / 100) % 10
-
- in2 := pc[2]
- in2Mode := (pc[0] / 1000) % 10
-
- var numToEval int
- if in1Mode == positionMode {
- numToEval = program[in1]
- } else {
- numToEval = in1
- }
-
- var targetPosition int
- if in2Mode == positionMode {
- targetPosition = program[in2]
- } else {
- targetPosition = in2
- }
-
- // Jump if it's zero.
- if numToEval == 0 {
- pc = program[targetPosition:]
- } else {
- pc = pc[3:]
- }
- case 7:
- // less than
- in1 := pc[1]
- in1Mode := (pc[0] / 100) % 10
-
- in2 := pc[2]
- in2Mode := (pc[0] / 1000) % 10
-
- outPos := pc[3]
-
- var left int
- if in1Mode == positionMode {
- left = program[in1]
- } else {
- left = in1
- }
-
- var right int
- if in2Mode == positionMode {
- right = program[in2]
- } else {
- right = in2
- }
-
- if left < right {
- program[outPos] = 1
- } else {
- program[outPos] = 0
- }
- pc = pc[4:]
- case 8:
- // less than
- in1 := pc[1]
- in1Mode := (pc[0] / 100) % 10
-
- in2 := pc[2]
- in2Mode := (pc[0] / 1000) % 10
-
- outPos := pc[3]
-
- var left int
- if in1Mode == positionMode {
- left = program[in1]
- } else {
- left = in1
- }
-
- var right int
- if in2Mode == positionMode {
- right = program[in2]
- } else {
- right = in2
- }
-
- if left == right {
- program[outPos] = 1
- } else {
- program[outPos] = 0
- }
- pc = pc[4:]
- case 99:
- return program
+ // Output returns 'PAUSE' so we need to call it till we encounter
+ // the `HALT` instruction.
+ if c.Eval(input) == computer.HALT {
+ break
}
+ // We only need a valid input on the first execution.
+ input = nil
}
-}
-
-func main() {
- print("Initialising STDIN reader... ")
- reader = bufio.NewReader(os.Stdin)
- println("FINISHED")
+ fmt.Printf("Answer: %d\n", c.Output)
- programCopy := make([]int, len(intCodeProgram))
+ fmt.Println("============= PART 2 =============")
+ programCopy = make([]int, len(intCodeProgram))
copy(programCopy, intCodeProgram)
- eval(programCopy)
+ c = computer.NewComputer(programCopy)
+ c.Eval([]int{5})
+ fmt.Printf("Answer: %d\n", c.Output)
}
M cmd/day7/main.go => cmd/day7/main.go +50 -296
@@ 1,10 1,8 @@
package main
import (
- "bufio"
"fmt"
- "strconv"
- "strings"
+ computer "git.sr.ht/~zacbrown/aoc-2019-go"
)
var intCodeProgram = []int{
@@ 31,240 29,6 @@ var intCodeProgram = []int{
3, 9, 101, 2, 9, 9, 4, 9, 99,
}
-var reader *bufio.Reader
-
-const (
- positionMode = 0
- immediateMode = 1
-)
-
-type Program struct {
- inputs []string
- program []int
- output int
- pc []int
-}
-
-func newProgram(program []int, inputs []string) *Program {
- return &Program{inputs, program, 0, program[:]}
-}
-
-const (
- PAUSE = iota
- HALT
-)
-
-func (p *Program) eval() int {
- for {
- // If the instruction is 1002, we want the least two digits - the tens
- // and the ones position. To get this, we modulo by 100: 1002 % 100 = 02
- instr := p.pc[0] % 100
- // Perform whatever operation we're going to.
- switch instr {
- case 1:
- // Add
- in1 := p.pc[1]
- in1Mode := (p.pc[0] / 100) % 10
- in2 := p.pc[2]
- in2Mode := (p.pc[0] / 1000) % 10
- out := p.pc[3]
-
- var in1Value int
- if in1Mode == positionMode {
- in1Value = p.program[in1]
- } else {
- in1Value = in1
- }
-
- var in2Value int
- if in2Mode == positionMode {
- in2Value = p.program[in2]
- } else {
- in2Value = in2
- }
-
- p.program[out] = in1Value + in2Value
- p.pc = p.pc[4:]
- case 2:
- // Multiply
- in1 := p.pc[1]
- in1Mode := (p.pc[0] / 100) % 10
- in2 := p.pc[2]
- in2Mode := (p.pc[0] / 1000) % 10
- out := p.pc[3]
-
- var in1Value int
- if in1Mode == positionMode {
- in1Value = p.program[in1]
- } else {
- in1Value = in1
- }
-
- var in2Value int
- if in2Mode == positionMode {
- in2Value = p.program[in2]
- } else {
- in2Value = in2
- }
-
- p.program[out] = in1Value * in2Value
- p.pc = p.pc[4:]
- case 3:
- // Input
- print("input requested: ")
- inPos := p.pc[1]
- input := p.inputs[0] // Use a sentinel instead
- println(input)
- p.inputs = p.inputs[1:] // pop the head off
- input = strings.Trim(input, " \n\t")
-
- inputAsInt, err := strconv.Atoi(input)
- if err != nil {
- panic(fmt.Sprintf("Non-integer input provided: %s. Err: %v", input, err))
- }
-
- p.program[inPos] = inputAsInt
- p.pc = p.pc[2:]
- case 4:
- // Output
- outPos := p.pc[1]
- outMode := (p.pc[0] / 100) % 10
-
- if outMode == positionMode {
- println(p.program[outPos])
- p.output = p.program[outPos]
- } else {
- println(outPos)
- p.output = outPos
- }
-
- outputVal := strconv.Itoa(p.output)
- p.inputs = append(p.inputs, outputVal)
-
- p.pc = p.pc[2:]
- return PAUSE
- case 5:
- // jump-if-true
- in1 := p.pc[1]
- in1Mode := (p.pc[0] / 100) % 10
-
- in2 := p.pc[2]
- in2Mode := (p.pc[0] / 1000) % 10
-
- var numToEval int
- if in1Mode == positionMode {
- numToEval = p.program[in1]
- } else {
- numToEval = in1
- }
-
- var targetPosition int
- if in2Mode == positionMode {
- targetPosition = p.program[in2]
- } else {
- targetPosition = in2
- }
-
- // Jump if it's non-zero.
- if numToEval != 0 {
- p.pc = p.program[targetPosition:]
- } else {
- p.pc = p.pc[3:]
- }
- case 6:
- // jump-if-false
- in1 := p.pc[1]
- in1Mode := (p.pc[0] / 100) % 10
-
- in2 := p.pc[2]
- in2Mode := (p.pc[0] / 1000) % 10
-
- var numToEval int
- if in1Mode == positionMode {
- numToEval = p.program[in1]
- } else {
- numToEval = in1
- }
-
- var targetPosition int
- if in2Mode == positionMode {
- targetPosition = p.program[in2]
- } else {
- targetPosition = in2
- }
-
- // Jump if it's zero.
- if numToEval == 0 {
- p.pc = p.program[targetPosition:]
- } else {
- p.pc = p.pc[3:]
- }
- case 7:
- // less than
- in1 := p.pc[1]
- in1Mode := (p.pc[0] / 100) % 10
-
- in2 := p.pc[2]
- in2Mode := (p.pc[0] / 1000) % 10
-
- outPos := p.pc[3]
-
- var left int
- if in1Mode == positionMode {
- left = p.program[in1]
- } else {
- left = in1
- }
-
- var right int
- if in2Mode == positionMode {
- right = p.program[in2]
- } else {
- right = in2
- }
-
- if left < right {
- p.program[outPos] = 1
- } else {
- p.program[outPos] = 0
- }
- p.pc = p.pc[4:]
- case 8:
- // less than
- in1 := p.pc[1]
- in1Mode := (p.pc[0] / 100) % 10
-
- in2 := p.pc[2]
- in2Mode := (p.pc[0] / 1000) % 10
-
- outPos := p.pc[3]
-
- var left int
- if in1Mode == positionMode {
- left = p.program[in1]
- } else {
- left = in1
- }
-
- var right int
- if in2Mode == positionMode {
- right = p.program[in2]
- } else {
- right = in2
- }
-
- if left == right {
- p.program[outPos] = 1
- } else {
- p.program[outPos] = 0
- }
- p.pc = p.pc[4:]
- case 99:
- return HALT
- }
- }
-}
-
var phaseSettingValuePart1 = []int{0, 1, 2, 3, 4}
var phaseSettingValuePart2 = []int{5, 6, 7, 8, 9}
var phaseSettingPermutations [][]int
@@ 296,57 60,55 @@ func part1() int {
// A
programCopyA := make([]int, len(intCodeProgram))
copy(programCopyA, intCodeProgram)
- phaseSetting := strconv.Itoa(permutation[0])
println("phase setting A: ", permutation[0])
- inputSignal := "0"
- pA := newProgram(programCopyA, []string{
- phaseSetting,
- inputSignal,
+ pA := computer.NewComputer(programCopyA)
+ pA.Eval([]int{
+ permutation[0],
+ 0,
})
- pA.eval()
// B
programCopyB := make([]int, len(intCodeProgram))
copy(programCopyB, intCodeProgram)
println("phase setting B: ", permutation[1])
- pB := newProgram(programCopyB, []string{
- strconv.Itoa(permutation[1]),
- strconv.Itoa(pA.output),
+ pB := computer.NewComputer(programCopyB)
+ pB.Eval([]int{
+ permutation[1],
+ pA.Output,
})
- pB.eval()
// C
programCopyC := make([]int, len(intCodeProgram))
copy(programCopyC, intCodeProgram)
println("phase setting C: ", permutation[2])
- pC := newProgram(programCopyC, []string{
- strconv.Itoa(permutation[2]),
- strconv.Itoa(pB.output),
+ pC := computer.NewComputer(programCopyC)
+ pC.Eval([]int{
+ permutation[2],
+ pB.Output,
})
- pC.eval()
// D
programCopyD := make([]int, len(intCodeProgram))
copy(programCopyD, intCodeProgram)
println("phase setting D: ", permutation[3])
- pD := newProgram(programCopyD, []string{
- strconv.Itoa(permutation[3]),
- strconv.Itoa(pC.output),
+ pD := computer.NewComputer(programCopyD)
+ pD.Eval([]int{
+ permutation[3],
+ pC.Output,
})
- pD.eval()
// E
programCopyE := make([]int, len(intCodeProgram))
copy(programCopyE, intCodeProgram)
println("phase setting E: ", permutation[4])
- pE := newProgram(programCopyE, []string{
- strconv.Itoa(permutation[4]),
- strconv.Itoa(pD.output),
+ pE := computer.NewComputer(programCopyE)
+ pE.Eval([]int{
+ permutation[4],
+ pD.Output,
})
- pE.eval()
- if pE.output > highSignal {
- highSignal = pE.output
+ if pE.Output > highSignal {
+ highSignal = pE.Output
}
}
return highSignal
@@ 362,87 124,79 @@ func part2() int {
// A
programCopyA := make([]int, len(intCodeProgram))
copy(programCopyA, intCodeProgram)
- phaseSetting := strconv.Itoa(permutation[0])
- inputSignal := "0"
- pA := newProgram(programCopyA, []string{
- phaseSetting,
+ inputSignal := 0
+ pA := computer.NewComputer(programCopyA)
+ pA.Eval( []int{
+ permutation[0],
inputSignal,
})
- pA.eval()
// B
programCopyB := make([]int, len(intCodeProgram))
copy(programCopyB, intCodeProgram)
- pB := newProgram(programCopyB, []string{
- strconv.Itoa(permutation[1]),
- strconv.Itoa(pA.output),
+ pB := computer.NewComputer(programCopyB)
+ pB.Eval([]int{
+ permutation[1],
+ pA.Output,
})
- pB.eval()
// C
programCopyC := make([]int, len(intCodeProgram))
copy(programCopyC, intCodeProgram)
- pC := newProgram(programCopyC, []string{
- strconv.Itoa(permutation[2]),
- strconv.Itoa(pB.output),
+ pC := computer.NewComputer(programCopyC)
+ pC.Eval([]int{
+ permutation[2],
+ pB.Output,
})
- pC.eval()
// D
programCopyD := make([]int, len(intCodeProgram))
copy(programCopyD, intCodeProgram)
- pD := newProgram(programCopyD, []string{
- strconv.Itoa(permutation[3]),
- strconv.Itoa(pC.output),
+ pD := computer.NewComputer(programCopyD)
+ pD.Eval([]int{
+ permutation[3],
+ pC.Output,
})
- pD.eval()
// E
programCopyE := make([]int, len(intCodeProgram))
copy(programCopyE, intCodeProgram)
- pE := newProgram(programCopyE, []string{
- strconv.Itoa(permutation[4]),
- strconv.Itoa(pD.output),
+ pE := computer.NewComputer(programCopyE)
+ pE.Eval([]int{
+ permutation[4],
+ pD.Output,
})
- pE.eval()
for {
- // Phase settings are set. Now grab the output from first run of E.
- pA.inputs = []string{strconv.Itoa(pE.output)}
-
// Now run them in feedback mode.
println("Run part A")
- if pA.eval() == HALT {
+ if pA.Eval([]int{pE.Output}) == computer.HALT {
break
}
- pB.inputs = []string{strconv.Itoa(pA.output)}
println("Run part B")
- if pB.eval() == HALT {
+ if pB.Eval([]int{pA.Output}) == computer.HALT {
panic("we halted at B?")
}
- pC.inputs = []string{strconv.Itoa(pB.output)}
println("Run part C")
- if pC.eval() == HALT {
+ if pC.Eval([]int{pB.Output}) == computer.HALT {
panic("we halted at C?")
}
- pD.inputs = []string{strconv.Itoa(pC.output)}
println("Run part D")
- if pD.eval() == HALT {
+ if pD.Eval([]int{pC.Output}) == computer.HALT {
panic("we halted at D?")
}
- pE.inputs = []string{strconv.Itoa(pD.output)}
println("Run part E")
- if pE.eval() == HALT {
+ if pE.Eval([]int{pD.Output}) == computer.HALT {
panic("we halted at E?")
}
}
- if pE.output > highSignal {
- highSignal = pE.output
+ if pE.Output > highSignal {
+ highSignal = pE.Output
}
}
return highSignal
M cmd/day8/main.go => cmd/day8/main.go +1 -1
@@ 39,7 39,7 @@ const (
type Layer [imageHeight][imageWidth]int
func buildImageLayers(imageData string) []Layer {
- layers := []Layer{}
+ var layers []Layer
imageDataIdx := 0
for imageDataIdx < len(imageData) {
A computer.go => computer.go +248 -0
@@ 0,0 1,248 @@
+package computer
+
+const (
+ PositionMode = 0
+ ImmediateMode = 1
+)
+
+type Computer struct {
+ inputs []int
+ program []int
+ Output int
+ pc []int
+}
+
+func NewComputer(program []int) *Computer {
+ return &Computer{nil, program, 0, program[:]}
+}
+
+const (
+ PAUSE = iota
+ HALT
+)
+
+func (c *Computer) instrAdd() {
+ // Add
+ in1 := c.pc[1]
+ in1Mode := (c.pc[0] / 100) % 10
+ in2 := c.pc[2]
+ in2Mode := (c.pc[0] / 1000) % 10
+ out := c.pc[3]
+
+ var in1Value int
+ if in1Mode == PositionMode {
+ in1Value = c.program[in1]
+ } else {
+ in1Value = in1
+ }
+
+ var in2Value int
+ if in2Mode == PositionMode {
+ in2Value = c.program[in2]
+ } else {
+ in2Value = in2
+ }
+
+ c.program[out] = in1Value + in2Value
+ c.pc = c.pc[4:]
+}
+
+func (c *Computer) instrMultiply() {
+ in1 := c.pc[1]
+ in1Mode := (c.pc[0] / 100) % 10
+ in2 := c.pc[2]
+ in2Mode := (c.pc[0] / 1000) % 10
+ out := c.pc[3]
+
+ var in1Value int
+ if in1Mode == PositionMode {
+ in1Value = c.program[in1]
+ } else {
+ in1Value = in1
+ }
+
+ var in2Value int
+ if in2Mode == PositionMode {
+ in2Value = c.program[in2]
+ } else {
+ in2Value = in2
+ }
+
+ c.program[out] = in1Value * in2Value
+ c.pc = c.pc[4:]
+}
+
+func (c *Computer) instrInput() {
+ inPos := c.pc[1]
+
+ c.program[inPos] = c.inputs[0]
+ c.inputs = c.inputs[1:] // pop the head off
+
+ c.pc = c.pc[2:]
+}
+
+func (c *Computer) instrOutput() {
+ outPos := c.pc[1]
+ outMode := (c.pc[0] / 100) % 10
+
+ if outMode == PositionMode {
+ c.Output = c.program[outPos]
+ } else {
+ c.Output = outPos
+ }
+
+ println("[DIAG] Output instruction: ", c.Output)
+
+ c.pc = c.pc[2:]
+}
+
+func (c *Computer) instrJumpIfTrue() {
+ in1 := c.pc[1]
+ in1Mode := (c.pc[0] / 100) % 10
+
+ in2 := c.pc[2]
+ in2Mode := (c.pc[0] / 1000) % 10
+
+ var numToEval int
+ if in1Mode == PositionMode {
+ numToEval = c.program[in1]
+ } else {
+ numToEval = in1
+ }
+
+ var targetPosition int
+ if in2Mode == PositionMode {
+ targetPosition = c.program[in2]
+ } else {
+ targetPosition = in2
+ }
+
+ // Jump if it's non-zero.
+ if numToEval != 0 {
+ c.pc = c.program[targetPosition:]
+ } else {
+ c.pc = c.pc[3:]
+ }
+}
+
+func (c *Computer) instrJumpIfFalse() {
+ in1 := c.pc[1]
+ in1Mode := (c.pc[0] / 100) % 10
+
+ in2 := c.pc[2]
+ in2Mode := (c.pc[0] / 1000) % 10
+
+ var numToEval int
+ if in1Mode == PositionMode {
+ numToEval = c.program[in1]
+ } else {
+ numToEval = in1
+ }
+
+ var targetPosition int
+ if in2Mode == PositionMode {
+ targetPosition = c.program[in2]
+ } else {
+ targetPosition = in2
+ }
+
+ // Jump if it's zero.
+ if numToEval == 0 {
+ c.pc = c.program[targetPosition:]
+ } else {
+ c.pc = c.pc[3:]
+ }
+}
+
+func (c *Computer) instrLessThan() {
+ in1 := c.pc[1]
+ in1Mode := (c.pc[0] / 100) % 10
+
+ in2 := c.pc[2]
+ in2Mode := (c.pc[0] / 1000) % 10
+
+ outPos := c.pc[3]
+
+ var left int
+ if in1Mode == PositionMode {
+ left = c.program[in1]
+ } else {
+ left = in1
+ }
+
+ var right int
+ if in2Mode == PositionMode {
+ right = c.program[in2]
+ } else {
+ right = in2
+ }
+
+ if left < right {
+ c.program[outPos] = 1
+ } else {
+ c.program[outPos] = 0
+ }
+ c.pc = c.pc[4:]
+}
+
+func (c *Computer) instrEqual() {
+ in1 := c.pc[1]
+ in1Mode := (c.pc[0] / 100) % 10
+
+ in2 := c.pc[2]
+ in2Mode := (c.pc[0] / 1000) % 10
+
+ outPos := c.pc[3]
+
+ var left int
+ if in1Mode == PositionMode {
+ left = c.program[in1]
+ } else {
+ left = in1
+ }
+
+ var right int
+ if in2Mode == PositionMode {
+ right = c.program[in2]
+ } else {
+ right = in2
+ }
+
+ if left == right {
+ c.program[outPos] = 1
+ } else {
+ c.program[outPos] = 0
+ }
+ c.pc = c.pc[4:]
+}
+
+func (c *Computer) Eval(inputs []int) int {
+ c.inputs = inputs
+ for {
+ // If the instruction is 1002, we want the least two digits - the tens
+ // and the ones position. To get this, we modulo by 100: 1002 % 100 = 02
+ instr := c.pc[0] % 100
+ // Perform whatever operation we're going to.
+ switch instr {
+ case 1:
+ c.instrAdd()
+ case 2:
+ c.instrMultiply()
+ case 3:
+ c.instrInput()
+ case 4:
+ c.instrOutput()
+ return PAUSE
+ case 5:
+ c.instrJumpIfTrue()
+ case 6:
+ c.instrJumpIfFalse()
+ case 7:
+ c.instrLessThan()
+ case 8:
+ c.instrEqual()
+ case 99:
+ return HALT
+ }
+ }
+}<
\ No newline at end of file