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