Browse Source

Make VM users responsible for its I/O channels.

master
Chris Smith 4 years ago
parent
commit
1bff4d5af4
Signed by: Chris Smith <chris@chameth.com> GPG Key ID: 3A2D4BBDC4A3C9A9
5 changed files with 17 additions and 17 deletions
  1. 1
    1
      02/main.go
  2. 4
    1
      05/main.go
  3. 4
    1
      07/main.go
  4. 4
    12
      intcode/vm.go
  5. 4
    2
      intcode/vm_test.go

+ 1
- 1
02/main.go View File

@@ -39,7 +39,7 @@ func main() {
39 39
 
40 40
 	pool := &sync.Pool{
41 41
 		New: func() interface{} {
42
-			return intcode.NewVirtualMachine(make([]int, len(input)), false)
42
+			return intcode.NewVirtualMachine(make([]int, len(input)))
43 43
 		},
44 44
 	}
45 45
 

+ 4
- 1
05/main.go View File

@@ -22,12 +22,15 @@ func main() {
22 22
 	memory := make([]int, len(input))
23 23
 	copy(memory, input)
24 24
 
25
-	vm := intcode.NewVirtualMachine(memory, true)
25
+	vm := intcode.NewVirtualMachine(memory)
26
+	vm.Input = make(chan int, 1)
27
+	vm.Output = make(chan int, 1)
26 28
 	vm.Input <- 1
27 29
 	go vm.Run()
28 30
 	fmt.Println(last(vm.Output))
29 31
 
30 32
 	vm.Reset(input)
33
+	vm.Output = make(chan int, 1)
31 34
 	vm.Input <- 5
32 35
 	go vm.Run()
33 36
 	fmt.Println(last(vm.Output))

+ 4
- 1
07/main.go View File

@@ -12,7 +12,8 @@ func runPipeline(memoryBanks []int, program []int, ps []int, feedback bool) int
12 12
 	for i := 0; i < len(ps); i++ {
13 13
 		memory := memoryBanks[i*len(program) : (i+1)*len(program)]
14 14
 		copy(memory, program)
15
-		vms[i] = intcode.NewVirtualMachine(memory, true)
15
+		vms[i] = intcode.NewVirtualMachine(memory)
16
+		vms[i].Output = make(chan int, 2)
16 17
 	}
17 18
 
18 19
 	// Link all the inputs and outputs
@@ -21,6 +22,8 @@ func runPipeline(memoryBanks []int, program []int, ps []int, feedback bool) int
21 22
 			vm.Input = vms[i-1].Output
22 23
 		} else if feedback {
23 24
 			vm.Input = vms[len(vms)-1].Output
25
+		} else {
26
+			vm.Input = make(chan int, 2)
24 27
 		}
25 28
 	}
26 29
 

+ 4
- 12
intcode/vm.go View File

@@ -10,23 +10,19 @@ type VirtualMachine struct {
10 10
 	Output chan int
11 11
 }
12 12
 
13
-// NewVirtualMachine creates a new IntCode virtual machine, initialised
14
-// to the given slice of memory.
15
-func NewVirtualMachine(memory []int, hasIO bool) *VirtualMachine {
13
+// NewVirtualMachine creates a new IntCode virtual machine, initialised to the given slice of memory.
14
+// The caller is responsible for initialising the VM's I/O channels if required.
15
+func NewVirtualMachine(memory []int) *VirtualMachine {
16 16
 	vm := &VirtualMachine{
17 17
 		ip:     0,
18 18
 		Memory: memory,
19 19
 		Halted: false,
20 20
 	}
21 21
 
22
-	if hasIO {
23
-		vm.Input = make(chan int, 1)
24
-		vm.Output = make(chan int, 1)
25
-	}
26
-
27 22
 	return vm
28 23
 }
29 24
 
25
+// arg Returns the value of the given argument for the current instruction.
30 26
 func (vm *VirtualMachine) arg(pos int) int {
31 27
 	mask := uint8(1) << uint8(pos)
32 28
 	if vm.modes&mask == mask {
@@ -63,8 +59,4 @@ func (vm *VirtualMachine) Reset(memory []int) {
63 59
 	copy(vm.Memory, memory)
64 60
 	vm.ip = 0
65 61
 	vm.Halted = false
66
-	if vm.Input != nil {
67
-		vm.Input = make(chan int, 1)
68
-		vm.Output = make(chan int, 1)
69
-	}
70 62
 }

+ 4
- 2
intcode/vm_test.go View File

@@ -17,7 +17,7 @@ func TestDayTwoSamples(t *testing.T) {
17 17
 	}
18 18
 
19 19
 	for _, table := range tables {
20
-		vm := NewVirtualMachine(table.given, false)
20
+		vm := NewVirtualMachine(table.given)
21 21
 		vm.Run()
22 22
 		if !reflect.DeepEqual(table.expected, vm.Memory) {
23 23
 			t.Errorf("Evaluation of %v was incorrect, got: %v, want: %v.", table.given, vm.Memory, table.expected)
@@ -48,7 +48,9 @@ func TestDayFiveSamples(t *testing.T) {
48 48
 	}
49 49
 
50 50
 	for _, table := range tables {
51
-		vm := NewVirtualMachine(table.given, true)
51
+		vm := NewVirtualMachine(table.given)
52
+		vm.Input = make(chan int, 1)
53
+		vm.Output = make(chan int, 1)
52 54
 
53 55
 		for _, v := range table.input {
54 56
 			vm.Input <- v

Loading…
Cancel
Save