package main import ( "AOC2022/helper" "fmt" "math" "strconv" "strings" ) type Operation struct { value int apes [2]string operator string hasValue bool } func main() { //args := os.Args[1:] lines := helper.ReadTextFile("day21/input") //part1(lines) fmt.Println(part2(lines)) fmt.Println(testNumber(lines, 3403989691757)) } func part2(lines []string) int { currentBestDifference := 99999999999999 currentI := 0 for currentBestDifference > 0 { startingDifference := testNumber(lines, currentI) fmt.Println(startingDifference) increaseDifference := testNumber(lines, currentI+1) reduceDifference := testNumber(lines, currentI-1) if increaseDifference < reduceDifference { fmt.Println("Up we go") currentI, currentBestDifference = checkForward(lines, currentBestDifference, currentI) } else { fmt.Println("Down we go") currentI, currentBestDifference = checkBackward(lines, currentBestDifference, currentI) } } fmt.Println(currentI) return 0 } func checkForward(lines []string, increaseDifference int, startI int) (int, int) { i := startI increaser := 1000000000 for increaser > 0 { differenceDoesntDecreaseAnymore := false for !differenceDoesntDecreaseAnymore { i += increaser tmpDifference := testNumber(lines, i) if tmpDifference < increaseDifference { increaseDifference = tmpDifference } else { i -= increaser differenceDoesntDecreaseAnymore = true } } increaser /= 10 } return i, increaseDifference } func checkBackward(lines []string, increaseDifference int, startI int) (int, int) { i := startI increaser := 1000000000 for increaser > 0 { differenceDoesntDecreaseAnymore := false for !differenceDoesntDecreaseAnymore { i -= increaser tmpDifference := testNumber(lines, i) if tmpDifference < increaseDifference { increaseDifference = tmpDifference } else { i += increaser differenceDoesntDecreaseAnymore = true } } increaser /= 10 } return i, increaseDifference } func testNumber(lines []string, testnumber int) int { apes := make(map[string]Operation) apesWithValue := []string{} apesWithOutValue := []string{} for _, line := range lines { id, operation := getApe(line) apes[id] = operation if len(operation.operator) > 0 { apesWithOutValue = append(apesWithOutValue, id) } else { apesWithValue = append(apesWithValue, id) } } humnApe := apes["humn"] humnApe.value = testnumber apes["humn"] = humnApe for len(apesWithOutValue) > 1 { apesWithOutValue = step(apesWithOutValue, &apes) } rootApe1Val := apes[apes["root"].apes[0]].value rootApe2Val := apes[apes["root"].apes[1]].value return int(math.Abs(float64(rootApe1Val - rootApe2Val))) } func part1(lines []string) { apes := make(map[string]Operation) apesWithValue := []string{} apesWithOutValue := []string{} for _, line := range lines { id, operation := getApe(line) apes[id] = operation if len(operation.operator) > 0 { apesWithOutValue = append(apesWithOutValue, id) } else { apesWithValue = append(apesWithValue, id) } } fmt.Println(apesWithValue) fmt.Println(apesWithOutValue) for len(apesWithOutValue) > 0 { apesWithOutValue = step(apesWithOutValue, &apes) } fmt.Print(apes["root"]) } func step(apesWithOutValue []string, apes *map[string]Operation) []string { newApesWithoutValue := []string{} for _, id := range apesWithOutValue { ape := (*apes)[id] ape1 := (*apes)[ape.apes[0]] ape2 := (*apes)[ape.apes[1]] if ape1.hasValue && ape2.hasValue { ape.value = calcOperation(ape1.value, ape2.value, ape.operator) ape.hasValue = true (*apes)[id] = ape } else { newApesWithoutValue = append(newApesWithoutValue, id) } } return newApesWithoutValue } func getApe(line string) (id string, operation Operation) { splitLine := strings.Split(line, ": ") id = splitLine[0] if strings.ContainsAny(splitLine[1], " ") { operationLine := strings.Split(splitLine[1], " ") operation.apes[0] = operationLine[0] operation.apes[1] = operationLine[2] operation.operator = string(operationLine[1][0]) } else { operation.hasValue = true operation.value = helper.RemoveError(strconv.Atoi(splitLine[1])) } return } func calcOperation(val1, val2 int, op string) int { switch op { case "*": return val1 * val2 case "/": return val1 / val2 case "+": return val1 + val2 case "-": return val1 - val2 default: return -99999999999999 } }