151 lines
4.0 KiB
Go
151 lines
4.0 KiB
Go
package main
|
|
|
|
import (
|
|
"AOC2021/src/helper"
|
|
"fmt"
|
|
"os"
|
|
"sort"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
func main() {
|
|
args := os.Args[1:]
|
|
input, err := helper.GetInput(args[0])
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
commandsSplitAtInput := [][]string{}
|
|
for _, command := range input {
|
|
if helper.ContainsCharacter(command, "inp") {
|
|
commandsSplitAtInput = append(commandsSplitAtInput, []string{})
|
|
}
|
|
commandsSplitAtInput[len(commandsSplitAtInput)-1] = append(commandsSplitAtInput[len(commandsSplitAtInput)-1], command)
|
|
}
|
|
vars := [][3]int{}
|
|
for _, commmands := range commandsSplitAtInput {
|
|
var1, _ := strconv.Atoi(strings.Split(commmands[5], " ")[2])
|
|
var2, _ := strconv.Atoi(strings.Split(commmands[15], " ")[2])
|
|
var3, _ := strconv.Atoi(strings.Split(commmands[4], " ")[2])
|
|
vars = append(vars, [3]int{var1, var2, var3})
|
|
}
|
|
|
|
possibleNumbers := make(map[string]int)
|
|
possibleNumbers[""] = 0
|
|
for i := 0; i < 14; i++ {
|
|
possibleNumbers = getAllPossibleNumbers(possibleNumbers, vars)
|
|
}
|
|
|
|
possibleNumbersInt := []int{}
|
|
for possibleNumberString, z := range possibleNumbers {
|
|
if z == 0 {
|
|
possibleNumberInt, _ := strconv.Atoi(possibleNumberString)
|
|
possibleNumbersInt = append(possibleNumbersInt, possibleNumberInt)
|
|
}
|
|
}
|
|
sort.Ints(possibleNumbersInt)
|
|
fmt.Println(possibleNumbersInt[len(possibleNumbersInt)-1])
|
|
fmt.Println(possibleNumbersInt[0])
|
|
|
|
//
|
|
//possibleNumbers := make(map[string]int)
|
|
//possibleNumbers[""] = 10
|
|
//testNumber := []int{9, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
|
|
//fmt.Println(checkNumber(testNumber, vars, 0, 0))
|
|
//alu := make(map[rune]int)
|
|
//alu['w'] = 0
|
|
//alu['x'] = 0
|
|
//alu['y'] = 0
|
|
//alu['z'] = 0
|
|
//for i, digit := range testNumber {
|
|
// step(&alu, commandsSplitAtInput[i], digit)
|
|
//}
|
|
//fmt.Println(alu)
|
|
|
|
}
|
|
|
|
func getAllPossibleNumbers(possibleNumbers map[string]int, vars [][3]int) map[string]int {
|
|
newPossibleNumbers := make(map[string]int)
|
|
for possibleNumber, z := range possibleNumbers {
|
|
tmpNewPossibleNumber := getPossibleNumbers(vars, z, possibleNumber)
|
|
for k, v := range tmpNewPossibleNumber {
|
|
newPossibleNumbers[k] = v
|
|
}
|
|
}
|
|
return newPossibleNumbers
|
|
}
|
|
|
|
func getPossibleNumbers(vars [][3]int, z int, pastDigits string) map[string]int {
|
|
digitsWithZ := make(map[string]int)
|
|
for i := 1; i < 10; i++ {
|
|
resultZ := checkNumber([]int{i}, vars, z, len(pastDigits))
|
|
if resultZ != -1 {
|
|
digitsWithZ[pastDigits+strconv.Itoa(i)] = resultZ
|
|
}
|
|
}
|
|
return digitsWithZ
|
|
}
|
|
|
|
func checkNumber(number []int, vars [][3]int, z int, amountPastDigits int) int {
|
|
currentVars := amountPastDigits
|
|
for _, digit := range number {
|
|
if vars[currentVars][0] < 0 && (z%26)+vars[currentVars][0] != digit {
|
|
return -1
|
|
}
|
|
z, _ = stepSimplified(z, digit, vars[currentVars])
|
|
if z < 0 {
|
|
return -1
|
|
}
|
|
currentVars++
|
|
}
|
|
return z
|
|
}
|
|
|
|
func stepSimplified(z, w int, vars [3]int) (int, int) {
|
|
newZ := z / vars[2]
|
|
if (z%26)+vars[0] == w {
|
|
z = newZ
|
|
} else {
|
|
z = (26 * newZ) + vars[1] + w
|
|
}
|
|
return z, w
|
|
}
|
|
|
|
func step(alu *map[rune]int, commands []string, inputVal int) {
|
|
for _, command := range commands {
|
|
splitCommand := strings.Split(command, " ")
|
|
switch splitCommand[0] {
|
|
case "inp":
|
|
(*alu)[rune(splitCommand[1][0])] = inputVal
|
|
break
|
|
case "mul":
|
|
(*alu)[rune(splitCommand[1][0])] = (*alu)[rune(splitCommand[1][0])] * getRightValue(alu, splitCommand[2])
|
|
break
|
|
case "add":
|
|
(*alu)[rune(splitCommand[1][0])] = (*alu)[rune(splitCommand[1][0])] + getRightValue(alu, splitCommand[2])
|
|
break
|
|
case "div":
|
|
(*alu)[rune(splitCommand[1][0])] = (*alu)[rune(splitCommand[1][0])] / getRightValue(alu, splitCommand[2])
|
|
break
|
|
case "mod":
|
|
(*alu)[rune(splitCommand[1][0])] = (*alu)[rune(splitCommand[1][0])] % getRightValue(alu, splitCommand[2])
|
|
break
|
|
case "eql":
|
|
if (*alu)[rune(splitCommand[1][0])] == getRightValue(alu, splitCommand[2]) {
|
|
(*alu)[rune(splitCommand[1][0])] = 1
|
|
} else {
|
|
(*alu)[rune(splitCommand[1][0])] = 0
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func getRightValue(alu *map[rune]int, commandRight string) int {
|
|
intValue, err := strconv.Atoi(commandRight)
|
|
if err != nil {
|
|
return (*alu)[rune(commandRight[0])]
|
|
} else {
|
|
return intValue
|
|
}
|
|
}
|