Piotr Czajkowski 1 tahun lalu
induk
melakukan
c8c4dcf880
1 mengubah file dengan 85 tambahan dan 22 penghapusan
  1. 85 22
      17/code.go

+ 85 - 22
17/code.go

@@ -8,7 +8,10 @@ import (
 	"sort"
 )
 
-const Diff = 48
+const (
+	Diff     = 48
+	MaxMoves = 3
+)
 
 func readInput(file *os.File) [][]int {
 	scanner := bufio.NewScanner(file)
@@ -51,12 +54,16 @@ type Destination struct {
 
 func getNorth(board [][]int, height int, width int, lava Destination) []Destination {
 	var destinations []Destination
-	moves := 3
+	moves := 0
 	if lava.direction == North {
 		moves = lava.moves
 	}
 
-	end := lava.pos.y - moves
+	if moves > MaxMoves {
+		return destinations
+	}
+
+	end := lava.pos.y - MaxMoves
 	if end < 0 {
 		end = 0
 	}
@@ -64,7 +71,11 @@ func getNorth(board [][]int, height int, width int, lava Destination) []Destinat
 	cost := lava.cost
 	for y := lava.pos.y - 1; y >= end; y-- {
 		cost += board[y][lava.pos.x]
-		moves--
+		moves++
+		if moves > MaxMoves {
+			break
+		}
+
 		destinations = append(destinations, Destination{pos: Point{y: y, x: lava.pos.x}, moves: moves, cost: cost, direction: North})
 	}
 
@@ -73,12 +84,16 @@ func getNorth(board [][]int, height int, width int, lava Destination) []Destinat
 
 func getEast(board [][]int, height int, width int, lava Destination) []Destination {
 	var destinations []Destination
-	moves := 3
+	moves := 0
 	if lava.direction == East {
 		moves = lava.moves
 	}
 
-	end := lava.pos.x + moves
+	if moves > MaxMoves {
+		return destinations
+	}
+
+	end := lava.pos.x + MaxMoves
 	if end >= width {
 		end = width - 1
 	}
@@ -86,8 +101,15 @@ func getEast(board [][]int, height int, width int, lava Destination) []Destinati
 	cost := lava.cost
 	for x := lava.pos.x + 1; x <= end; x++ {
 		cost += board[lava.pos.y][x]
-		moves--
+		moves++
+		if moves > MaxMoves {
+			break
+		}
+
 		destinations = append(destinations, Destination{pos: Point{y: lava.pos.y, x: x}, moves: moves, cost: cost, direction: East})
+		if moves > MaxMoves {
+			break
+		}
 	}
 
 	return destinations
@@ -95,12 +117,16 @@ func getEast(board [][]int, height int, width int, lava Destination) []Destinati
 
 func getSouth(board [][]int, height int, width int, lava Destination) []Destination {
 	var destinations []Destination
-	moves := 3
+	moves := 0
 	if lava.direction == South {
 		moves = lava.moves
 	}
 
-	end := lava.pos.y + moves
+	if moves > MaxMoves {
+		return destinations
+	}
+
+	end := lava.pos.y + MaxMoves
 	if end >= height {
 		end = height - 1
 	}
@@ -108,7 +134,11 @@ func getSouth(board [][]int, height int, width int, lava Destination) []Destinat
 	cost := lava.cost
 	for y := lava.pos.y + 1; y <= end; y++ {
 		cost += board[y][lava.pos.x]
-		moves--
+		moves++
+		if moves > MaxMoves {
+			break
+		}
+
 		destinations = append(destinations, Destination{pos: Point{y: y, x: lava.pos.x}, moves: moves, cost: cost, direction: South})
 	}
 
@@ -117,12 +147,16 @@ func getSouth(board [][]int, height int, width int, lava Destination) []Destinat
 
 func getWest(board [][]int, height int, width int, lava Destination) []Destination {
 	var destinations []Destination
-	moves := 3
+	moves := 0
 	if lava.direction == West {
 		moves = lava.moves
 	}
 
-	end := lava.pos.x - moves
+	if moves > MaxMoves {
+		return destinations
+	}
+
+	end := lava.pos.x - MaxMoves
 	if end < 0 {
 		end = 0
 	}
@@ -130,16 +164,36 @@ func getWest(board [][]int, height int, width int, lava Destination) []Destinati
 	cost := lava.cost
 	for x := lava.pos.x - 1; x >= end; x-- {
 		cost += board[lava.pos.y][x]
-		moves--
+		moves++
+		if moves > MaxMoves {
+			break
+		}
+
 		destinations = append(destinations, Destination{pos: Point{y: lava.pos.y, x: x}, moves: moves, cost: cost, direction: West})
 	}
 
 	return destinations
 }
 
+func getDirections(direction int) []int {
+	switch direction {
+	case North:
+		return []int{West, North, East}
+	case East:
+		return []int{North, East, South}
+	case South:
+		return []int{West, South, East}
+	case West:
+		return []int{South, West, North}
+	}
+
+	return []int{}
+}
+
 func getDestinations(board [][]int, height int, width int, lava Destination) []Destination {
 	var destinations []Destination
-	for i := lava.direction - 1; i <= lava.direction+1; i++ {
+	directions := getDirections(lava.direction)
+	for i := range directions {
 		switch i {
 		case North:
 			destinations = append(destinations, getNorth(board, height, width, lava)...)
@@ -161,21 +215,23 @@ func part1(board [][]int) int {
 	width := len(board[0])
 	goal := Point{y: height - 1, x: width - 1}
 	explored := make(map[Point]int)
-	lava := Destination{pos: Point{x: 0, y: 0}, moves: 3, direction: East}
-	frontier := getDestinations(board, height, width, lava)
+	lava := Destination{pos: Point{x: 0, y: 0}, moves: 0, direction: East}
+	prev := lava
+	frontier := []Destination{lava}
 
 	for {
 		if len(frontier) == 0 {
 			break
 		}
 
-		sort.Slice(frontier, func(i, j int) bool {
-			return frontier[i].cost < frontier[j].cost
-		})
-
 		current := frontier[0]
 		frontier = frontier[1:]
 
+		if current.direction == prev.direction && current.moves+prev.moves > MaxMoves {
+			continue
+		}
+
+		prev = current
 		if current.pos == goal {
 			if min > current.cost {
 				min = current.cost
@@ -183,13 +239,20 @@ func part1(board [][]int) int {
 		}
 
 		successors := getDestinations(board, height, width, current)
+		fmt.Println(current, successors)
 		for i := range successors {
+			newCost := successors[i].cost + successors[i].moves
 			value, ok := explored[successors[i].pos]
-			if !ok || value > successors[i].cost {
-				explored[successors[i].pos] = successors[i].cost
+			if !ok || value > newCost {
+				explored[successors[i].pos] = newCost
 				frontier = append(frontier, successors[i])
 			}
 		}
+
+		sort.Slice(frontier, func(i, j int) bool {
+			return frontier[i].cost < frontier[j].cost
+		})
+
 	}
 
 	return min