Improve day 24

This commit is contained in:
2022-12-24 16:17:50 +01:00
parent e42cd31ec0
commit e49ac1b231

View File

@@ -22,6 +22,7 @@ type Map struct {
height int height int
width int width int
cache [][][]int cache [][][]int
bestDistance int
} }
func (tileMap *Map) InitCache() { func (tileMap *Map) InitCache() {
@@ -35,6 +36,7 @@ func (tileMap *Map) InitCache() {
} }
} }
} }
tileMap.bestDistance = math.MaxInt32
} }
func (tileMap *Map) GetDistanceToEnd(currentSteps int) int { func (tileMap *Map) GetDistanceToEnd(currentSteps int) int {
@@ -48,8 +50,6 @@ func (tileMap *Map) GetDistanceToEnd(currentSteps int) int {
break break
} }
} }
tileMap.cache[startSteps][0][startCol] = currentSteps
tileMap.PropagateDistanceFromTile(startSteps, startCol, 0, currentSteps)
endCol := 0 endCol := 0
for i := 0; i < tileMap.width; i++ { for i := 0; i < tileMap.width; i++ {
@@ -59,13 +59,10 @@ func (tileMap *Map) GetDistanceToEnd(currentSteps int) int {
} }
} }
minDistance := math.MaxInt32 tileMap.cache[startSteps][0][startCol] = currentSteps
for i := 0; i < tileMap.steps; i++ { tileMap.PropagateDistanceFromTile(startSteps, startCol, 0, currentSteps, endCol, len(tileMap.tiles[startSteps])-1)
if tileMap.cache[i][len(tileMap.tiles[0])-1][endCol] < minDistance {
minDistance = tileMap.cache[i][len(tileMap.tiles[0])-1][endCol] return tileMap.bestDistance
}
}
return minDistance
} }
func (tileMap *Map) GetDistanceToStart(currentSteps int) int { func (tileMap *Map) GetDistanceToStart(currentSteps int) int {
@@ -79,8 +76,6 @@ func (tileMap *Map) GetDistanceToStart(currentSteps int) int {
break break
} }
} }
tileMap.cache[startSteps][len(tileMap.tiles[startSteps])-1][endCol] = currentSteps
tileMap.PropagateDistanceFromTile(startSteps, endCol, len(tileMap.tiles[startSteps])-1, currentSteps)
startCol := 0 startCol := 0
for i := 0; i < tileMap.width; i++ { for i := 0; i < tileMap.width; i++ {
@@ -90,37 +85,61 @@ func (tileMap *Map) GetDistanceToStart(currentSteps int) int {
} }
} }
minDistance := math.MaxInt32 tileMap.cache[startSteps][len(tileMap.tiles[startSteps])-1][endCol] = currentSteps
for i := 0; i < tileMap.steps; i++ { tileMap.PropagateDistanceFromTile(startSteps, endCol, len(tileMap.tiles[startSteps])-1, currentSteps, startCol, 0)
if tileMap.cache[i][0][startCol] < minDistance {
minDistance = tileMap.cache[i][0][startCol] return tileMap.bestDistance
}
}
return minDistance
} }
func (tileMap *Map) PropagateDistanceFromTile(step, x, y, currentDistance int) { func (tileMap *Map) PropagateDistanceFromTile(step, x, y, currentDistance, targetX, targetY int) {
nextStep := (step + 1) % tileMap.steps nextStep := (step + 1) % tileMap.steps
orders := []byte{0, 1, 2, 3, 4}
distances := []int{(x-targetX)*(x-targetX)+(y+1-targetY)*(y+1-targetY),
(x+1-targetX)*(x+1-targetX)+(y-targetY)*(y-targetY),
(x-targetX)*(x-targetX)+(y-targetY)*(y-targetY),
(x-1-targetX)*(x-1-targetX)+(y-targetY)*(y-targetY),
(x-targetX)*(x-targetX)+(y-1-targetY)*(y-1-targetY)}
if x > 0 && tileMap.tiles[nextStep][y][x-1] == Empty && currentDistance + 1 < tileMap.cache[nextStep][y][x-1] { if currentDistance >= tileMap.bestDistance {
tileMap.cache[nextStep][y][x-1] = currentDistance + 1 return
tileMap.PropagateDistanceFromTile(nextStep, x-1, y, currentDistance+1)
} }
if x < tileMap.width - 1 && tileMap.tiles[nextStep][y][x+1] == Empty && currentDistance + 1 < tileMap.cache[nextStep][y][x+1] {
tileMap.cache[nextStep][y][x+1] = currentDistance + 1 if x == targetX && y == targetY {
tileMap.PropagateDistanceFromTile(nextStep, x+1, y, currentDistance+1) tileMap.bestDistance = currentDistance
} }
if y > 0 && tileMap.tiles[nextStep][y-1][x] == Empty && currentDistance + 1 < tileMap.cache[nextStep][y-1][x] {
tileMap.cache[nextStep][y-1][x] = currentDistance + 1 sorted := false
tileMap.PropagateDistanceFromTile(nextStep, x, y-1, currentDistance+1) for !sorted {
sorted = true
for i := 0; i < 4; i++ {
if distances[orders[i]] > distances[orders[i+1]] {
orders[i], orders[i+1] = orders[i+1], orders[i]
sorted = false
}
}
} }
if y < tileMap.height - 1 && tileMap.tiles[nextStep][y+1][x] == Empty && currentDistance + 1 < tileMap.cache[nextStep][y+1][x] {
tileMap.cache[nextStep][y+1][x] = currentDistance + 1 for _, order := range orders {
tileMap.PropagateDistanceFromTile(nextStep, x, y+1, currentDistance+1) if order == 0 && y < tileMap.height - 1 && tileMap.tiles[nextStep][y+1][x] == Empty && currentDistance + 1 < tileMap.cache[nextStep][y+1][x] {
} tileMap.cache[nextStep][y+1][x] = currentDistance + 1
if tileMap.tiles[nextStep][y][x] == Empty && currentDistance + 1 < tileMap.cache[nextStep][y][x] { tileMap.PropagateDistanceFromTile(nextStep, x, y+1, currentDistance+1, targetX, targetY)
tileMap.cache[nextStep][y][x] = currentDistance + 1 }
tileMap.PropagateDistanceFromTile(nextStep, x, y, currentDistance+1) if order == 1 && x < tileMap.width - 1 && tileMap.tiles[nextStep][y][x+1] == Empty && currentDistance + 1 < tileMap.cache[nextStep][y][x+1] {
tileMap.cache[nextStep][y][x+1] = currentDistance + 1
tileMap.PropagateDistanceFromTile(nextStep, x+1, y, currentDistance+1, targetX, targetY)
}
if order == 2 && tileMap.tiles[nextStep][y][x] == Empty && currentDistance + 1 < tileMap.cache[nextStep][y][x] {
tileMap.cache[nextStep][y][x] = currentDistance + 1
tileMap.PropagateDistanceFromTile(nextStep, x, y, currentDistance+1, targetX, targetY)
}
if order == 3 && x > 0 && tileMap.tiles[nextStep][y][x-1] == Empty && currentDistance + 1 < tileMap.cache[nextStep][y][x-1] {
tileMap.cache[nextStep][y][x-1] = currentDistance + 1
tileMap.PropagateDistanceFromTile(nextStep, x-1, y, currentDistance+1, targetX, targetY)
}
if order == 4 && y > 0 && tileMap.tiles[nextStep][y-1][x] == Empty && currentDistance + 1 < tileMap.cache[nextStep][y-1][x] {
tileMap.cache[nextStep][y-1][x] = currentDistance + 1
tileMap.PropagateDistanceFromTile(nextStep, x, y-1, currentDistance+1, targetX, targetY)
}
} }
} }