2022-12-12 21:54:34 +01:00
package main
import (
"AOC2022/helper"
"fmt"
)
type FieldPoint struct {
cost int
height int
2022-12-12 23:26:26 +01:00
before [ 2 ] int
2022-12-12 21:54:34 +01:00
}
func main ( ) {
//args := os.Args[1:]
2022-12-12 23:26:26 +01:00
lines := helper . ReadTextFile ( "day12/inputFichte" )
2022-12-12 21:54:34 +01:00
start , end := getStartingPointAndEndpoint ( lines )
fmt . Println ( start )
fmt . Println ( end )
field := getField ( lines )
2022-12-12 23:26:26 +01:00
part1 ( field , end )
print ( field )
//fastestPath := part2(lines, field, end)
}
func part2 ( lines [ ] string , field [ ] [ ] FieldPoint , end [ 2 ] int ) {
lowestPoints := getLowestPoints ( lines )
fastestPath := 999999
for _ , point := range lowestPoints {
activePoints := make ( map [ [ 2 ] int ] struct { } )
activePoints [ [ 2 ] int { point [ 0 ] , point [ 1 ] } ] = struct { } { }
field = getField ( lines )
steps := getBestRouteLength ( activePoints , field , end )
if steps < fastestPath && steps != 0 {
fastestPath = steps
2022-12-12 21:54:34 +01:00
}
}
2022-12-12 23:26:26 +01:00
fmt . Println ( fastestPath )
}
func part1 ( field [ ] [ ] FieldPoint , end [ 2 ] int ) {
activePoints := make ( map [ [ 2 ] int ] struct { } )
activePoints [ [ 2 ] int { 0 , 0 } ] = struct { } { }
fmt . Println ( getBestRouteLength ( activePoints , field , end ) + 2 )
2022-12-12 21:54:34 +01:00
}
func getField ( lines [ ] string ) [ ] [ ] FieldPoint {
field := make ( [ ] [ ] FieldPoint , len ( lines ) )
for i := 0 ; i < len ( lines ) ; i ++ {
line := lines [ i ]
fieldLine := make ( [ ] FieldPoint , len ( line ) )
for j := 0 ; j < len ( line ) ; j ++ {
height := int ( line [ j ] )
if line [ j ] == 'S' {
height = int ( 'a' )
}
if line [ j ] == 'E' {
height = int ( 'z' )
}
2022-12-12 23:26:26 +01:00
fieldLine [ j ] = FieldPoint { 0 , height , [ 2 ] int { - 1 , - 1 } }
2022-12-12 21:54:34 +01:00
}
2022-12-12 23:26:26 +01:00
field [ i ] = fieldLine
2022-12-12 21:54:34 +01:00
}
return field
}
2022-12-12 23:26:26 +01:00
func getBestRouteLength ( activePoints map [ [ 2 ] int ] struct { } , field [ ] [ ] FieldPoint , endPoint [ 2 ] int ) int {
for len ( activePoints ) > 0 {
step ( & field , & activePoints )
2022-12-12 21:54:34 +01:00
}
2022-12-12 23:26:26 +01:00
return field [ endPoint [ 0 ] ] [ endPoint [ 1 ] ] . cost
}
func step ( field * [ ] [ ] FieldPoint , activePoints * map [ [ 2 ] int ] struct { } ) {
point := get_some_key ( * activePoints )
delete ( * activePoints , point )
current0 := point [ 0 ]
current1 := point [ 1 ]
currentFieldSumCost := ( * field ) [ current0 ] [ current1 ] . cost
directions := [ 4 ] [ 2 ] int { { 0 , - 1 } , { + 1 , 0 } , { 0 , 1 } , { - 1 , 0 } }
for _ , direction := range directions {
toVisit0 := current0 + direction [ 0 ]
toVisit1 := current1 + direction [ 1 ]
if checkVisitable ( point , direction , * field ) {
cost := 1 + currentFieldSumCost
if ( * field ) [ toVisit0 ] [ toVisit1 ] . cost > cost || ( * field ) [ toVisit0 ] [ toVisit1 ] . cost == 0 {
( * field ) [ toVisit0 ] [ toVisit1 ] . cost = cost
( * field ) [ toVisit0 ] [ toVisit1 ] . before = [ 2 ] int { current0 , current1 }
( * activePoints ) [ [ 2 ] int { toVisit0 , toVisit1 } ] = struct { } { }
}
}
2022-12-12 21:54:34 +01:00
}
}
2022-12-12 23:26:26 +01:00
func checkVisitable ( activePosition [ 2 ] int , direction [ 2 ] int , field [ ] [ ] FieldPoint ) ( visitable bool ) {
toVisit := activePosition
2022-12-12 21:54:34 +01:00
toVisit [ 0 ] += direction [ 0 ]
toVisit [ 1 ] += direction [ 1 ]
if toVisit [ 0 ] > - 1 && toVisit [ 1 ] > - 1 &&
2022-12-12 23:26:26 +01:00
toVisit [ 0 ] < len ( field ) && toVisit [ 1 ] < len ( ( field ) [ 0 ] ) &&
field [ activePosition [ 0 ] ] [ activePosition [ 1 ] ] . before != toVisit {
heightToVisit := field [ toVisit [ 0 ] ] [ toVisit [ 1 ] ] . height
heightCurrentPos := field [ activePosition [ 0 ] ] [ activePosition [ 1 ] ] . height + 1
2022-12-12 21:54:34 +01:00
if heightToVisit > heightCurrentPos {
return false
}
return true
}
return false
}
func getStartingPointAndEndpoint ( field [ ] string ) ( start , end [ 2 ] int ) {
for i := 0 ; i < len ( field ) ; i ++ {
for j := 0 ; j < len ( field [ i ] ) ; j ++ {
if field [ i ] [ j ] == 'S' {
start = [ 2 ] int { i , j }
}
if field [ i ] [ j ] == 'E' {
end = [ 2 ] int { i , j }
}
}
}
return
}
2022-12-12 23:26:26 +01:00
func getLowestPoints ( field [ ] string ) [ ] [ 2 ] int {
lowestPoints := [ ] [ 2 ] int { }
2022-12-12 21:54:34 +01:00
for i := 0 ; i < len ( field ) ; i ++ {
for j := 0 ; j < len ( field [ i ] ) ; j ++ {
2022-12-12 23:26:26 +01:00
if field [ i ] [ j ] == 'a' {
lowestPoints = append ( lowestPoints , [ 2 ] int { i , j } )
2022-12-12 21:54:34 +01:00
}
}
2022-12-12 23:26:26 +01:00
}
return lowestPoints
}
func get_some_key ( m map [ [ 2 ] int ] struct { } ) [ 2 ] int {
for k := range m {
return k
}
return [ 2 ] int { - 1 , - 1 }
}
func print ( field [ ] [ ] FieldPoint ) {
for i := 0 ; i < len ( field ) ; i ++ {
fieldLine := field [ i ]
tempArray := [ ] int { }
for j := 0 ; j < len ( fieldLine ) ; j ++ {
tempArray = append ( tempArray , fieldLine [ j ] . height - 96 )
}
fmt . Println ( tempArray )
}
fmt . Println ( )
for i := 0 ; i < len ( field ) ; i ++ {
fieldLine := field [ i ]
tempArray := [ ] int { }
for j := 0 ; j < len ( fieldLine ) ; j ++ {
tempArray = append ( tempArray , fieldLine [ j ] . cost )
}
fmt . Println ( tempArray )
2022-12-12 21:54:34 +01:00
}
}