|  | @@ -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))
 | 
	
		
			
				|  |  |  }
 |