Browse Source

Day 19

master
Chris Smith 4 years ago
parent
commit
35e0df463a
Signed by: Chris Smith <chris@chameth.com> GPG Key ID: 3A2D4BBDC4A3C9A9
6 changed files with 115 additions and 17 deletions
  1. 1
    3
      15/main.go
  2. 2
    0
      19/answers.txt
  3. 1
    0
      19/input.txt
  4. 54
    0
      19/main.go
  5. 15
    2
      intcode/ops.go
  6. 42
    12
      intcode/vm.go

+ 1
- 3
15/main.go View File

@@ -67,9 +67,7 @@ func explore(vm *intcode.VirtualMachine) (grid [100][100]tile, stepsToOxygen int
67 67
 				}
68 68
 
69 69
 				vmp := s.vm.Clone()
70
-				go vmp.Run()
71
-				vmp.Input <- int(d)
72
-				state := <-vmp.Output
70
+				state := *vmp.RunForInput(int(d))
73 71
 
74 72
 				if state == 0 {
75 73
 					grid[yp][xp] = wall

+ 2
- 0
19/answers.txt View File

@@ -0,0 +1,2 @@
1
+141
2
+15641348

+ 1
- 0
19/input.txt View File

@@ -0,0 +1 @@
1
+109,424,203,1,21102,11,1,0,1105,1,282,21102,1,18,0,1105,1,259,1201,1,0,221,203,1,21101,0,31,0,1105,1,282,21102,38,1,0,1106,0,259,21001,23,0,2,22101,0,1,3,21101,0,1,1,21102,1,57,0,1105,1,303,2101,0,1,222,21001,221,0,3,20102,1,221,2,21102,259,1,1,21101,80,0,0,1106,0,225,21101,0,111,2,21102,1,91,0,1105,1,303,2102,1,1,223,20101,0,222,4,21102,1,259,3,21102,1,225,2,21102,1,225,1,21101,0,118,0,1105,1,225,20101,0,222,3,21102,148,1,2,21102,1,133,0,1106,0,303,21202,1,-1,1,22001,223,1,1,21102,148,1,0,1106,0,259,2101,0,1,223,20102,1,221,4,21001,222,0,3,21101,0,17,2,1001,132,-2,224,1002,224,2,224,1001,224,3,224,1002,132,-1,132,1,224,132,224,21001,224,1,1,21101,0,195,0,106,0,109,20207,1,223,2,20102,1,23,1,21102,-1,1,3,21101,0,214,0,1105,1,303,22101,1,1,1,204,1,99,0,0,0,0,109,5,2102,1,-4,249,22101,0,-3,1,21202,-2,1,2,21202,-1,1,3,21102,1,250,0,1105,1,225,22102,1,1,-4,109,-5,2106,0,0,109,3,22107,0,-2,-1,21202,-1,2,-1,21201,-1,-1,-1,22202,-1,-2,-2,109,-3,2105,1,0,109,3,21207,-2,0,-1,1206,-1,294,104,0,99,22102,1,-2,-2,109,-3,2106,0,0,109,5,22207,-3,-4,-1,1206,-1,346,22201,-4,-3,-4,21202,-3,-1,-1,22201,-4,-1,2,21202,2,-1,-1,22201,-4,-1,1,21202,-2,1,3,21101,0,343,0,1105,1,303,1105,1,415,22207,-2,-3,-1,1206,-1,387,22201,-3,-2,-3,21202,-2,-1,-1,22201,-3,-1,3,21202,3,-1,-1,22201,-3,-1,2,21201,-4,0,1,21102,384,1,0,1106,0,303,1105,1,415,21202,-4,-1,-4,22201,-4,-3,-4,22202,-3,-2,-2,22202,-2,-4,-4,22202,-3,-2,-3,21202,-4,-1,-2,22201,-3,-2,1,21202,1,1,-4,109,-5,2106,0,0

+ 54
- 0
19/main.go View File

@@ -0,0 +1,54 @@
1
+package main
2
+
3
+import (
4
+	"fmt"
5
+	"github.com/csmith/aoc-2019/common"
6
+	"github.com/csmith/aoc-2019/intcode"
7
+)
8
+
9
+const shipSize = 100
10
+
11
+func main() {
12
+	input := common.ReadCsvAsInts("19/input.txt")
13
+	vm := intcode.NewVirtualMachine(make([]int, len(input)))
14
+
15
+	var endPositions [shipSize]int
16
+	endIndex := 0
17
+
18
+	sum := 0
19
+	lastStart := 0
20
+	for y := 0; ; y++ {
21
+		first := 0
22
+
23
+		for x := lastStart; ; x++ {
24
+			vm.Reset(input)
25
+			if *vm.RunForInput(x, y) == 1 {
26
+				if first == 0 {
27
+					first = x
28
+				}
29
+				if x < 50 && y < 50 {
30
+					sum++
31
+				}
32
+			} else if first > 0 || y < 50 && x > 50 {
33
+				// For y < 50 if we hit x > 50 without finding the beam, assume it's not there. (The beam isn't
34
+				// continuous at the start, there's a couple of blanks).
35
+
36
+				if x-first >= shipSize-1 {
37
+					previousEnd := endPositions[endIndex]
38
+
39
+					if previousEnd-shipSize >= first-1 {
40
+						fmt.Println(sum)
41
+						fmt.Println((previousEnd-shipSize)*10000 + (y - 100))
42
+						return
43
+					}
44
+
45
+					endPositions[endIndex] = x
46
+					endIndex = (endIndex + 1) % shipSize
47
+				}
48
+				break
49
+			}
50
+		}
51
+
52
+		lastStart = first
53
+	}
54
+}

+ 15
- 2
intcode/ops.go View File

@@ -45,13 +45,26 @@ func mulOpcode(vm *VirtualMachine, arg1, arg2, arg3 *int) {
45 45
 
46 46
 // readOpCode reads a value from the input stream and stores it at the memory address given by arg 1.
47 47
 func readOpCode(vm *VirtualMachine, arg1, _, _ *int) {
48
-	*arg1 = <-vm.Input
48
+	if vm.inputIndex < len(vm.input) {
49
+		// Read from pre-provided values
50
+		*arg1 = vm.input[vm.inputIndex]
51
+		vm.inputIndex++
52
+	} else {
53
+		*arg1 = <-vm.Input
54
+	}
55
+
49 56
 	vm.ip += 2
50 57
 }
51 58
 
52 59
 // writeOpCode writes the value specified by the first argument to the output stream.
53 60
 func writeOpCode(vm *VirtualMachine, arg1, _, _ *int) {
54
-	vm.Output <- *arg1
61
+	if len(vm.input) > 0 {
62
+		// Running to get the value of some input, provide the output and halt
63
+		vm.output = arg1
64
+		vm.Halted = true
65
+	} else {
66
+		vm.Output <- *arg1
67
+	}
55 68
 	vm.ip += 2
56 69
 }
57 70
 

+ 42
- 12
intcode/vm.go View File

@@ -10,12 +10,15 @@ const (
10 10
 
11 11
 // VirtualMachine is an IntCode virtual machine.
12 12
 type VirtualMachine struct {
13
-	ip     int
14
-	rb     int
15
-	Memory []int
16
-	Halted bool
17
-	Input  chan int
18
-	Output chan int
13
+	ip         int
14
+	rb         int
15
+	Memory     []int
16
+	Halted     bool
17
+	Input      chan int
18
+	Output     chan int
19
+	input      []int
20
+	inputIndex int
21
+	output     *int
19 22
 }
20 23
 
21 24
 // NewVirtualMachine creates a new IntCode virtual machine, initialised to the given slice of memory.
@@ -36,15 +39,39 @@ func (vm *VirtualMachine) Clone() *VirtualMachine {
36 39
 	copy(memory, vm.Memory)
37 40
 
38 41
 	return &VirtualMachine{
39
-		ip:     vm.ip,
40
-		rb:     vm.rb,
41
-		Memory: memory,
42
-		Halted: vm.Halted,
43
-		Input:  make(chan int, 1),
44
-		Output: make(chan int, 1),
42
+		ip:         vm.ip,
43
+		rb:         vm.rb,
44
+		Memory:     memory,
45
+		Halted:     vm.Halted,
46
+		Input:      make(chan int, 1),
47
+		Output:     make(chan int, 1),
48
+		input:      vm.input,
49
+		inputIndex: vm.inputIndex,
50
+		output:     vm.output,
45 51
 	}
46 52
 }
47 53
 
54
+// Run repeatedly executes instructions until the VM produces output or halts.
55
+//
56
+// The given values will be provided as input whenever a read opcode is executed;
57
+// any further reads before an output will fallback to reading from the Input
58
+// channel.
59
+//
60
+// If the machine halts instead of outputting a number, this function will return
61
+// nil.
62
+func (vm *VirtualMachine) RunForInput(input ...int) *int {
63
+	vm.inputIndex = 0
64
+	vm.input = input
65
+	vm.Run()
66
+
67
+	// Reset the halted state so we can carry on running, if required
68
+	if vm.output != nil {
69
+		vm.Halted = false
70
+	}
71
+
72
+	return vm.output
73
+}
74
+
48 75
 // Run repeatedly executes instructions until the VM halts.
49 76
 func (vm *VirtualMachine) Run() {
50 77
 	var args [3]*int
@@ -98,5 +125,8 @@ func (vm *VirtualMachine) Reset(memory []int) {
98 125
 
99 126
 	vm.ip = 0
100 127
 	vm.rb = 0
128
+	vm.input = nil
129
+	vm.inputIndex = 0
130
+	vm.output = nil
101 131
 	vm.Halted = false
102 132
 }

Loading…
Cancel
Save