Day 7 solution
I will probably end up regretting this since I assume the "wait to be given an input from some other process before continuing execution" paradigm is going to come up again, but this part 2 goroutine+channel solution felt good (taking advantage of Go features) and made me happy, so I rolled with it.
This commit is contained in:
116
days/07.go
Normal file
116
days/07.go
Normal file
@ -0,0 +1,116 @@
|
||||
package days
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"parnic.com/aoc2019/utilities"
|
||||
)
|
||||
|
||||
type Day07 struct {
|
||||
program utilities.IntcodeProgram
|
||||
amps []utilities.IntcodeProgram
|
||||
}
|
||||
|
||||
func (d *Day07) Parse() {
|
||||
d.program = utilities.LoadIntcodeProgram("07p")
|
||||
d.amps = make([]utilities.IntcodeProgram, 5)
|
||||
for i := range d.amps {
|
||||
d.amps[i] = d.program.Copy()
|
||||
}
|
||||
}
|
||||
|
||||
func (d Day07) Num() int {
|
||||
return 7
|
||||
}
|
||||
|
||||
func (d *Day07) Part1() string {
|
||||
var highestVal int64
|
||||
var highestSequence []int64
|
||||
|
||||
allSequences := utilities.GetPermutations([]int64{0, 1, 2, 3, 4})
|
||||
for _, sequence := range allSequences {
|
||||
if len(sequence) != len(d.amps) {
|
||||
panic("input sequence does not match up to number of amplifiers")
|
||||
}
|
||||
|
||||
input := int64(0)
|
||||
var output int64
|
||||
for i, amp := range d.amps {
|
||||
amp.RunIn(func(step int) int64 {
|
||||
if step == 1 {
|
||||
return sequence[i]
|
||||
} else if step == 2 {
|
||||
return input
|
||||
}
|
||||
|
||||
panic("hit more input instructions than expected")
|
||||
}, func(val int64, state utilities.IntcodeProgramState) {
|
||||
output = val
|
||||
})
|
||||
|
||||
input = output
|
||||
}
|
||||
|
||||
if output > highestVal {
|
||||
highestVal = output
|
||||
if highestSequence == nil {
|
||||
highestSequence = make([]int64, len(sequence))
|
||||
}
|
||||
copy(highestSequence, sequence)
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Sprintf("Max thruster signal: %s%d%s (produced by %v)", utilities.TextBold, highestVal, utilities.TextReset, highestSequence)
|
||||
}
|
||||
|
||||
func (d *Day07) Part2() string {
|
||||
var highestVal int64
|
||||
var highestSequence []int64
|
||||
|
||||
allSequences := utilities.GetPermutations([]int64{5, 6, 7, 8, 9})
|
||||
for _, sequence := range allSequences {
|
||||
if len(sequence) != len(d.amps) {
|
||||
panic("input sequence does not match up to number of amplifiers")
|
||||
}
|
||||
|
||||
inputs := make([]chan int64, len(d.amps))
|
||||
for i := range d.amps {
|
||||
d.amps[i].Reset()
|
||||
inputs[i] = make(chan int64, 1)
|
||||
inputs[i] <- sequence[i]
|
||||
}
|
||||
|
||||
var finalOutput int64
|
||||
var wg sync.WaitGroup
|
||||
for i := range d.amps {
|
||||
wg.Add(1)
|
||||
go func(idx int) {
|
||||
d.amps[idx].RunIn(func(step int) int64 {
|
||||
input := <-inputs[idx]
|
||||
return input
|
||||
}, func(val int64, state utilities.IntcodeProgramState) {
|
||||
finalOutput = val
|
||||
inputIdx := idx + 1
|
||||
if inputIdx == len(inputs) {
|
||||
inputIdx = 0
|
||||
}
|
||||
inputs[inputIdx] <- val
|
||||
})
|
||||
wg.Done()
|
||||
}(i)
|
||||
}
|
||||
inputs[0] <- 0
|
||||
wg.Wait()
|
||||
|
||||
if finalOutput > highestVal {
|
||||
highestVal = finalOutput
|
||||
if highestSequence == nil {
|
||||
highestSequence = make([]int64, len(sequence))
|
||||
}
|
||||
copy(highestSequence, sequence)
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Sprintf("Max thruster signal: %s%d%s (produced by %v)", utilities.TextBold, highestVal, utilities.TextReset, highestSequence)
|
||||
}
|
1
inputs/07p.txt
Normal file
1
inputs/07p.txt
Normal file
@ -0,0 +1 @@
|
||||
3,8,1001,8,10,8,105,1,0,0,21,38,47,64,85,106,187,268,349,430,99999,3,9,1002,9,4,9,1001,9,4,9,1002,9,4,9,4,9,99,3,9,1002,9,4,9,4,9,99,3,9,1001,9,3,9,102,5,9,9,1001,9,5,9,4,9,99,3,9,101,3,9,9,102,5,9,9,1001,9,4,9,102,4,9,9,4,9,99,3,9,1002,9,3,9,101,2,9,9,102,4,9,9,101,2,9,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,99,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,2,9,9,4,9,3,9,101,1,9,9,4,9,99,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,99
|
1
inputs/07s1.txt
Normal file
1
inputs/07s1.txt
Normal file
@ -0,0 +1 @@
|
||||
3,15,3,16,1002,16,10,16,1,16,15,15,4,15,99,0,0
|
1
inputs/07s2.txt
Normal file
1
inputs/07s2.txt
Normal file
@ -0,0 +1 @@
|
||||
3,23,3,24,1002,24,10,24,1002,23,-1,23,101,5,23,23,1,24,23,23,4,23,99,0,0
|
1
inputs/07s3.txt
Normal file
1
inputs/07s3.txt
Normal file
@ -0,0 +1 @@
|
||||
3,31,3,32,1002,32,10,32,1001,31,-2,31,1007,31,0,33,1002,33,7,33,1,33,31,31,1,32,31,31,4,31,99,0,0,0
|
1
inputs/07s4.txt
Normal file
1
inputs/07s4.txt
Normal file
@ -0,0 +1 @@
|
||||
3,26,1001,26,-4,26,3,27,1002,27,2,27,1,27,26,27,4,27,1001,28,-1,28,1005,28,6,99,0,0,5
|
1
inputs/07s5.txt
Normal file
1
inputs/07s5.txt
Normal file
@ -0,0 +1 @@
|
||||
3,52,1001,52,-5,52,3,53,1,52,56,54,1007,54,5,55,1005,55,26,1001,54,-5,54,1105,1,12,1,53,54,53,1008,54,0,55,1001,55,1,55,2,53,55,53,4,53,1001,56,-1,56,1005,56,6,99,0,0,0,0,10
|
1
main.go
1
main.go
@ -37,6 +37,7 @@ var dayMap = []day{
|
||||
&days.Day04{},
|
||||
&days.Day05{},
|
||||
&days.Day06{},
|
||||
&days.Day07{},
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
34
utilities/permutations.go
Normal file
34
utilities/permutations.go
Normal file
@ -0,0 +1,34 @@
|
||||
package utilities
|
||||
|
||||
type Permutable interface {
|
||||
~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64
|
||||
}
|
||||
|
||||
func GetPermutations[T Permutable](arr []T) [][]T {
|
||||
var helper func([]T, int)
|
||||
res := [][]T{}
|
||||
|
||||
helper = func(arr []T, n int) {
|
||||
if n == 1 {
|
||||
tmp := make([]T, len(arr))
|
||||
copy(tmp, arr)
|
||||
res = append(res, tmp)
|
||||
} else {
|
||||
for i := 0; i < n; i++ {
|
||||
helper(arr, n-1)
|
||||
if n%2 == 1 {
|
||||
tmp := arr[i]
|
||||
arr[i] = arr[n-1]
|
||||
arr[n-1] = tmp
|
||||
} else {
|
||||
tmp := arr[0]
|
||||
arr[0] = arr[n-1]
|
||||
arr[n-1] = tmp
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
helper(arr, len(arr))
|
||||
return res
|
||||
}
|
Reference in New Issue
Block a user