Improve day 24
This commit is contained in:
@@ -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] {
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
tileMap.PropagateDistanceFromTile(nextStep, x, y+1, currentDistance+1, targetX, targetY)
|
||||
}
|
||||
if tileMap.tiles[nextStep][y][x] == Empty && currentDistance + 1 < tileMap.cache[nextStep][y][x] {
|
||||
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)
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user