diff --git a/days/07.go b/days/07.go new file mode 100644 index 0000000..42d3503 --- /dev/null +++ b/days/07.go @@ -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) +} diff --git a/inputs/07p.txt b/inputs/07p.txt new file mode 100644 index 0000000..8f225bb --- /dev/null +++ b/inputs/07p.txt @@ -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 \ No newline at end of file diff --git a/inputs/07s1.txt b/inputs/07s1.txt new file mode 100644 index 0000000..993e2e0 --- /dev/null +++ b/inputs/07s1.txt @@ -0,0 +1 @@ +3,15,3,16,1002,16,10,16,1,16,15,15,4,15,99,0,0 \ No newline at end of file diff --git a/inputs/07s2.txt b/inputs/07s2.txt new file mode 100644 index 0000000..1a7a957 --- /dev/null +++ b/inputs/07s2.txt @@ -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 \ No newline at end of file diff --git a/inputs/07s3.txt b/inputs/07s3.txt new file mode 100644 index 0000000..eb61459 --- /dev/null +++ b/inputs/07s3.txt @@ -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 \ No newline at end of file diff --git a/inputs/07s4.txt b/inputs/07s4.txt new file mode 100644 index 0000000..4363e8e --- /dev/null +++ b/inputs/07s4.txt @@ -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 \ No newline at end of file diff --git a/inputs/07s5.txt b/inputs/07s5.txt new file mode 100644 index 0000000..5ed292b --- /dev/null +++ b/inputs/07s5.txt @@ -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 \ No newline at end of file diff --git a/main.go b/main.go index 8931410..783362f 100644 --- a/main.go +++ b/main.go @@ -37,6 +37,7 @@ var dayMap = []day{ &days.Day04{}, &days.Day05{}, &days.Day06{}, + &days.Day07{}, } func main() { diff --git a/utilities/permutations.go b/utilities/permutations.go new file mode 100644 index 0000000..fa220b3 --- /dev/null +++ b/utilities/permutations.go @@ -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 +}