|
@@ -11,6 +11,7 @@ type Point struct {
|
|
|
y, x int
|
|
|
cost int
|
|
|
direction []int
|
|
|
+ parent *Point
|
|
|
}
|
|
|
|
|
|
func (p *Point) key() string {
|
|
@@ -62,7 +63,7 @@ var directions [][]int = [][]int{
|
|
|
func getMoves(reindeer Point, matrix [][]byte) []Point {
|
|
|
var moves []Point
|
|
|
for _, direction := range directions {
|
|
|
- move := Point{x: reindeer.x + direction[0], y: reindeer.y + direction[1], cost: reindeer.cost, direction: direction}
|
|
|
+ move := Point{x: reindeer.x + direction[0], y: reindeer.y + direction[1], cost: reindeer.cost, direction: direction, parent: &reindeer}
|
|
|
if matrix[move.y][move.x] != '#' {
|
|
|
if reindeer.direction[0] == direction[0] && reindeer.direction[1] == direction[1] {
|
|
|
move.cost++
|
|
@@ -77,28 +78,49 @@ func getMoves(reindeer Point, matrix [][]byte) []Point {
|
|
|
return moves
|
|
|
}
|
|
|
|
|
|
-func hike(reindeer *Point, matrix [][]byte) int {
|
|
|
+func hike(reindeer *Point, matrix [][]byte) (int, []*Point) {
|
|
|
cost := 1000000000
|
|
|
visited := make(map[string]int)
|
|
|
+ paths := make(map[int][]*Point)
|
|
|
|
|
|
moves := []Point{*reindeer}
|
|
|
for len(moves) > 0 {
|
|
|
current := moves[0]
|
|
|
moves = moves[1:]
|
|
|
- if matrix[current.y][current.x] == 'E' && current.cost < cost {
|
|
|
+ if matrix[current.y][current.x] == 'E' && current.cost <= cost {
|
|
|
cost = current.cost
|
|
|
+ paths[cost] = append(paths[cost], ¤t)
|
|
|
}
|
|
|
|
|
|
newMoves := getMoves(current, matrix)
|
|
|
for _, newMove := range newMoves {
|
|
|
- if visited[newMove.key()] == 0 || visited[newMove.key()] > newMove.cost {
|
|
|
+ if visited[newMove.key()] == 0 || visited[newMove.key()] >= newMove.cost {
|
|
|
moves = append(moves, newMove)
|
|
|
visited[newMove.key()] = newMove.cost
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- return cost
|
|
|
+ return cost, paths[cost]
|
|
|
+}
|
|
|
+
|
|
|
+func countTiles(paths []*Point) int {
|
|
|
+ var count int
|
|
|
+ checked := make(map[string]bool)
|
|
|
+
|
|
|
+ for _, path := range paths {
|
|
|
+ current := path
|
|
|
+ for current != nil {
|
|
|
+ if !checked[current.key()] {
|
|
|
+ checked[current.key()] = true
|
|
|
+ count++
|
|
|
+ }
|
|
|
+
|
|
|
+ current = current.parent
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return count
|
|
|
}
|
|
|
|
|
|
func main() {
|
|
@@ -113,5 +135,7 @@ func main() {
|
|
|
}
|
|
|
|
|
|
reindeer, matrix := readInput(file)
|
|
|
- fmt.Println("Part1:", hike(reindeer, matrix))
|
|
|
+ lowestCost, bestPaths := hike(reindeer, matrix)
|
|
|
+ fmt.Println("Part1:", lowestCost)
|
|
|
+ fmt.Println("Part2:", countTiles(bestPaths))
|
|
|
}
|