Improve day 24
This commit is contained in:
@@ -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] {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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.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.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