357 lines
6.6 KiB
Go
357 lines
6.6 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
"math"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
func main() {
|
|
file, err := os.Open("input.txt")
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer file.Close()
|
|
|
|
scanner := bufio.NewScanner(file)
|
|
if !scanner.Scan() {
|
|
log.Fatalln("Problem while read line.")
|
|
return
|
|
}
|
|
|
|
stringarr := strings.Split(scanner.Text(), ",")
|
|
var t2 = []int{}
|
|
|
|
for _, i := range stringarr {
|
|
j, err := strconv.Atoi(i)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
t2 = append(t2, j)
|
|
}
|
|
wip := make([]int, len(t2))
|
|
wip2 := make([]int, len(t2))
|
|
|
|
// ========= Finish now, we can solve the task ======
|
|
copy(wip, t2)
|
|
SolvePuzzle1(wip)
|
|
copy(wip2, t2)
|
|
SolvePuzzle2(wip2)
|
|
}
|
|
|
|
func SolvePuzzle1(list []int) {
|
|
|
|
rawr := []int{0, 1, 2, 3, 4}
|
|
combinations := permutations(rawr)
|
|
highestOutput := math.MinInt32
|
|
//highestInput := ""
|
|
|
|
for _, combi := range combinations {
|
|
output := RunAmplification(list, []int{int(combi[0]), int(combi[1]), int(combi[2]), int(combi[3]), int(combi[4])})
|
|
if output > highestOutput {
|
|
//highestInput = combi
|
|
highestOutput = output
|
|
}
|
|
}
|
|
log.Println("Part1: " + strconv.Itoa(highestOutput))
|
|
}
|
|
|
|
func SolvePuzzle2(list []int) {
|
|
|
|
rawr := []int{5, 6, 7, 8, 9}
|
|
combinations := permutations(rawr)
|
|
highestOutput := math.MinInt32
|
|
//highestInput := ""
|
|
|
|
for _, combi := range combinations {
|
|
output := RunRecursiveAmplification(list, []int{combi[0], combi[1], combi[2], combi[3], combi[4]})
|
|
if output > highestOutput {
|
|
//highestInput = combi
|
|
highestOutput = output
|
|
}
|
|
}
|
|
log.Println("Part2: " + strconv.Itoa(highestOutput))
|
|
}
|
|
|
|
func RunAmplification(list []int, phases []int) int {
|
|
signal := []string{"0"}
|
|
|
|
for i := 0; i < 5; i++ {
|
|
wip := make([]int, len(list))
|
|
copy(wip, list)
|
|
|
|
inputs := make([]int, 0)
|
|
inputs = append(inputs, phases[i])
|
|
for j := 0; j < len(signal); j++ {
|
|
inputStr, _ := strconv.Atoi(signal[j])
|
|
inputs = append(inputs, inputStr)
|
|
}
|
|
|
|
output, err, _, _ := ParseArray(wip, inputs, 0)
|
|
|
|
if err != nil {
|
|
log.Printf("Problem at Amplification: %d", i+1)
|
|
log.Fatal(err)
|
|
}
|
|
|
|
signal = output
|
|
}
|
|
sigInt, _ := strconv.Atoi(signal[0])
|
|
return sigInt
|
|
}
|
|
|
|
func RunRecursiveAmplification(list []int, phases []int) int {
|
|
signal := []string{"0"}
|
|
|
|
amplifier := make([][]int, 0)
|
|
startIndex := make([]int, 0)
|
|
|
|
for i := 0; i < 5; i++ {
|
|
if len(amplifier) <= i {
|
|
log.Println("APPPEND")
|
|
wip := make([]int, len(list))
|
|
copy(wip, list)
|
|
amplifier = append(amplifier, wip)
|
|
startIndex = append(startIndex, 0)
|
|
}
|
|
|
|
inputs := make([]int, 0)
|
|
inputs = append(inputs, phases[i])
|
|
for j := 0; j < len(signal); j++ {
|
|
inputStr, _ := strconv.Atoi(signal[j])
|
|
inputs = append(inputs, inputStr)
|
|
}
|
|
|
|
output, err, cmdSuccess, ind := ParseArray(amplifier[i], inputs, startIndex[i])
|
|
startIndex[i] = ind
|
|
|
|
if err != nil {
|
|
log.Printf("Problem at Amplification: %d", i+1)
|
|
log.Fatal(err)
|
|
}
|
|
|
|
signal = output
|
|
|
|
if i == 4 {
|
|
i = -1
|
|
|
|
if cmdSuccess {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
sigInt, _ := strconv.Atoi(signal[len(signal)-1])
|
|
fmt.Println(len(signal))
|
|
return sigInt
|
|
}
|
|
|
|
func ParseArray(list []int, inputs []int, startIndex int) ([]string, error, bool, int) {
|
|
var (
|
|
output []string
|
|
)
|
|
|
|
inputIndex := 0
|
|
output = make([]string, 0)
|
|
|
|
log.Println("=================")
|
|
for i := startIndex; i < len(list); i += 4 {
|
|
log.Println(strconv.Itoa(i) + " -> " + strconv.Itoa(list[i]))
|
|
cmd := list[i]
|
|
|
|
sum := 0
|
|
|
|
mode1 := 0
|
|
mode2 := 0
|
|
//mode3 := 0
|
|
|
|
count := CountDigits(cmd)
|
|
if count > 2 {
|
|
cmdStr := strconv.Itoa(cmd)
|
|
cmd, _ = strconv.Atoi(cmdStr[len(cmdStr)-2:])
|
|
|
|
if count >= 3 {
|
|
mode1, _ = strconv.Atoi(cmdStr[len(cmdStr)-3 : len(cmdStr)-2])
|
|
}
|
|
if count >= 4 {
|
|
mode2, _ = strconv.Atoi(cmdStr[len(cmdStr)-4 : len(cmdStr)-3])
|
|
}
|
|
if count >= 5 {
|
|
//mode3, _ = strconv.Atoi(cmdStr[len(cmdStr)-4:len(cmdStr)-3])
|
|
}
|
|
}
|
|
|
|
if cmd == 99 {
|
|
return output, nil, true, -2
|
|
}
|
|
|
|
if cmd == 1 {
|
|
num1 := -1
|
|
num2 := -1
|
|
if mode1 == 1 {
|
|
num1 = list[i+1]
|
|
} else {
|
|
num1 = list[list[i+1]]
|
|
}
|
|
if mode2 == 1 {
|
|
num2 = list[i+2]
|
|
} else {
|
|
num2 = list[list[i+2]]
|
|
}
|
|
sum = num1 + num2
|
|
list[list[i+3]] = sum
|
|
|
|
} else if cmd == 2 {
|
|
|
|
num1 := -1
|
|
num2 := -1
|
|
if mode1 == 1 {
|
|
num1 = list[i+1]
|
|
} else {
|
|
num1 = list[list[i+1]]
|
|
}
|
|
if mode2 == 1 {
|
|
num2 = list[i+2]
|
|
} else {
|
|
num2 = list[list[i+2]]
|
|
}
|
|
sum = num1 * num2
|
|
list[list[i+3]] = sum
|
|
} else if cmd == 3 {
|
|
if len(inputs) > inputIndex {
|
|
input := inputs[inputIndex]
|
|
inputIndex++
|
|
list[list[i+1]] = input
|
|
} else {
|
|
return output, nil, false, i
|
|
}
|
|
i = i - 2
|
|
} else if cmd == 4 {
|
|
if mode1 == 1 {
|
|
output = append(output, strconv.Itoa(list[i+1]))
|
|
} else {
|
|
output = append(output, strconv.Itoa(list[list[i+1]]))
|
|
}
|
|
i -= 2
|
|
} else if cmd == 5 {
|
|
num1 := -1
|
|
if mode1 == 1 {
|
|
num1 = list[i+1]
|
|
} else {
|
|
num1 = list[list[i+1]]
|
|
}
|
|
num2 := -1
|
|
if mode2 == 1 {
|
|
num2 = list[i+2]
|
|
} else {
|
|
num2 = list[list[i+2]]
|
|
}
|
|
if num1 != 0 {
|
|
i = num2 - 4
|
|
} else {
|
|
i -= 1
|
|
}
|
|
} else if cmd == 6 {
|
|
num1 := -1
|
|
if mode1 == 1 {
|
|
num1 = list[i+1]
|
|
} else {
|
|
num1 = list[list[i+1]]
|
|
}
|
|
num2 := -1
|
|
if mode2 == 1 {
|
|
num2 = list[i+2]
|
|
} else {
|
|
num2 = list[list[i+2]]
|
|
}
|
|
if num1 == 0 {
|
|
i = num2 - 4
|
|
} else {
|
|
i -= 1
|
|
}
|
|
} else if cmd == 7 {
|
|
num1 := -1
|
|
if mode1 == 1 {
|
|
num1 = list[i+1]
|
|
} else {
|
|
num1 = list[list[i+1]]
|
|
}
|
|
num2 := -1
|
|
if mode2 == 1 {
|
|
num2 = list[i+2]
|
|
} else {
|
|
num2 = list[list[i+2]]
|
|
}
|
|
if num1 < num2 {
|
|
list[list[i+3]] = 1
|
|
} else {
|
|
list[list[i+3]] = 0
|
|
}
|
|
} else if cmd == 8 {
|
|
num1 := -1
|
|
if mode1 == 1 {
|
|
num1 = list[i+1]
|
|
} else {
|
|
num1 = list[list[i+1]]
|
|
}
|
|
num2 := -1
|
|
if mode2 == 1 {
|
|
num2 = list[i+2]
|
|
} else {
|
|
num2 = list[list[i+2]]
|
|
}
|
|
if num1 == num2 {
|
|
list[list[i+3]] = 1
|
|
} else {
|
|
list[list[i+3]] = 0
|
|
}
|
|
} else {
|
|
return output, errors.New("Wrong Command (" + strconv.Itoa(list[i]) + ") at position " + strconv.Itoa(i)), false, -1
|
|
}
|
|
}
|
|
|
|
log.Println("NONE")
|
|
return output, nil, false, -1
|
|
}
|
|
|
|
func CountDigits(i int) int {
|
|
count := 0
|
|
for i != 0 {
|
|
i /= 10
|
|
count = count + 1
|
|
}
|
|
return count
|
|
}
|
|
|
|
func permutations(arr []int) [][]int {
|
|
var helper func([]int, int)
|
|
res := [][]int{}
|
|
|
|
helper = func(arr []int, n int) {
|
|
if n == 1 {
|
|
tmp := make([]int, 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
|
|
}
|