2022-12-21 18:37:32 +01:00
package main
import (
"AOC2022/helper"
"fmt"
2022-12-22 03:14:11 +01:00
"math"
2022-12-21 18:37:32 +01:00
"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" )
2022-12-22 03:14:11 +01:00
//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 ) {
2022-12-21 18:37:32 +01:00
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
}
}