2021 - Day 15
This commit is contained in:
parent
521697afbf
commit
269c347c40
9
2021/15/go.mod
Normal file
9
2021/15/go.mod
Normal file
|
@ -0,0 +1,9 @@
|
|||
module AoC/2021/15
|
||||
|
||||
require AoC/2021/common v0.0.0
|
||||
|
||||
require github.com/joho/godotenv v1.4.0 // indirect
|
||||
|
||||
replace AoC/2021/common v0.0.0 => ../common
|
||||
|
||||
go 1.17
|
2
2021/15/go.sum
Normal file
2
2021/15/go.sum
Normal file
|
@ -0,0 +1,2 @@
|
|||
github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=
|
||||
github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
224
2021/15/main.go
Normal file
224
2021/15/main.go
Normal file
|
@ -0,0 +1,224 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
aoc "AoC/2021/common"
|
||||
"bufio"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type Coord struct {
|
||||
x int;
|
||||
y int;
|
||||
}
|
||||
|
||||
func printGrid(grid [][]int) {
|
||||
for y := range grid {
|
||||
for _, c := range grid[y] {
|
||||
if c == 10000000 {
|
||||
fmt.Print("--- ")
|
||||
} else {
|
||||
fmt.Printf("%3d ", c)
|
||||
}
|
||||
}
|
||||
fmt.Print("\n")
|
||||
}
|
||||
}
|
||||
|
||||
func printSolution(weights [][]int) {
|
||||
current := Coord{len(weights[0])-1, len(weights)-1}
|
||||
|
||||
route := make([][]string, len(weights))
|
||||
for i := range weights {
|
||||
row := make([]string, len(weights[i]))
|
||||
for j := range row {
|
||||
row[j] = "."
|
||||
}
|
||||
route[i] = row
|
||||
}
|
||||
|
||||
route[current.y][current.x] = "x"
|
||||
|
||||
value := 10000000
|
||||
for !(current.x == 0 && current.y == 0) {
|
||||
neighbours := [4]Coord{{current.x+1, current.y}, {current.x-1, current.y}, {current.x, current.y+1}, {current.x, current.y-1}}
|
||||
for _, neighbour := range neighbours {
|
||||
if neighbour.y < 0 || neighbour.y >= len(weights) || neighbour.x < 0 || neighbour.x >= len(weights[neighbour.y]) {
|
||||
continue
|
||||
}
|
||||
|
||||
if weights[neighbour.y][neighbour.x] < value {
|
||||
value = weights[neighbour.y][neighbour.x]
|
||||
current = neighbour
|
||||
}
|
||||
}
|
||||
|
||||
route[current.y][current.x] = "#"
|
||||
}
|
||||
|
||||
route[0][0] = "x"
|
||||
|
||||
for y := range route {
|
||||
for _, c := range route[y] {
|
||||
fmt.Printf("%s", c)
|
||||
}
|
||||
fmt.Printf("\n")
|
||||
}
|
||||
}
|
||||
|
||||
func updateWeights(grid [][]int, weights [][]int, visited [][]bool, current Coord) ([][]int, []Coord) {
|
||||
neighbours := [4]Coord{{current.x+1, current.y}, {current.x-1, current.y}, {current.x, current.y+1}, {current.x, current.y-1}}
|
||||
var validNeighbours []Coord
|
||||
for _, neighbour := range neighbours {
|
||||
if neighbour.y < 0 || neighbour.y >= len(grid) || neighbour.x < 0 || neighbour.x >= len(grid[neighbour.y]) {
|
||||
continue
|
||||
}
|
||||
|
||||
if visited[neighbour.y][neighbour.x] {
|
||||
continue
|
||||
}
|
||||
|
||||
validNeighbours = append(validNeighbours, neighbour)
|
||||
|
||||
cost := weights[current.y][current.x] + grid[neighbour.y][neighbour.x]
|
||||
|
||||
if cost < weights[neighbour.y][neighbour.x] {
|
||||
weights[neighbour.y][neighbour.x] = cost
|
||||
}
|
||||
}
|
||||
|
||||
return weights, validNeighbours
|
||||
}
|
||||
|
||||
func minCost(grid [][]int, src Coord, dest Coord) int {
|
||||
// Create a grid of weights
|
||||
weights := make([][]int, len(grid))
|
||||
for i := range grid {
|
||||
row := make([]int, len(grid[i]))
|
||||
for j := range row {
|
||||
row[j] = 10000000
|
||||
}
|
||||
weights[i] = row
|
||||
}
|
||||
|
||||
visited := make([][]bool, len(grid))
|
||||
for i := range grid {
|
||||
row := make([]bool, len(grid[i]))
|
||||
for j := range row {
|
||||
row[j] = false
|
||||
}
|
||||
visited[i] = row
|
||||
}
|
||||
|
||||
// Set the cost of the src to 0
|
||||
weights[src.y][src.x] = 0
|
||||
|
||||
targets := []Coord{src}
|
||||
iters := 0
|
||||
for !(targets[0].x == dest.x && targets[0].y == dest.y) {
|
||||
var neighbours []Coord
|
||||
weights, neighbours = updateWeights(grid, weights, visited, targets[0])
|
||||
visited[targets[0].y][targets[0].x] = true
|
||||
|
||||
targets = append(targets[1:], neighbours...)
|
||||
|
||||
n := 0
|
||||
for _, t := range targets {
|
||||
if !visited[t.y][t.x] {
|
||||
targets[n] = t
|
||||
n++
|
||||
}
|
||||
}
|
||||
targets = targets[:n]
|
||||
|
||||
sort.Slice(targets, func(i, j int) bool {
|
||||
return weights[targets[i].y][targets[i].x] < weights[targets[j].y][targets[j].x]
|
||||
})
|
||||
|
||||
iters++
|
||||
}
|
||||
|
||||
// printSolution(weights)
|
||||
// fmt.Printf("Took %d iterations\n", iters)
|
||||
|
||||
return weights[dest.y][dest.x]
|
||||
}
|
||||
|
||||
func main() {
|
||||
challenge := aoc.New(2021, 15)
|
||||
|
||||
challenge.Test(`1163751742
|
||||
1381373672
|
||||
2136511328
|
||||
3694931569
|
||||
7463417111
|
||||
1319128137
|
||||
1359912421
|
||||
3125421639
|
||||
1293138521
|
||||
2311944581`, []int{40, 315})
|
||||
|
||||
challenge.Solution(1, func (input *bufio.Scanner) int {
|
||||
var grid [][]int
|
||||
for y := 0; input.Scan(); y++ {
|
||||
line := input.Text()
|
||||
|
||||
row := make([]int, len(line))
|
||||
|
||||
for i, c := range line {
|
||||
n, _ := strconv.Atoi(string(c))
|
||||
row[i] = n
|
||||
}
|
||||
|
||||
grid = append(grid, row)
|
||||
}
|
||||
|
||||
// printGrid(grid)
|
||||
|
||||
return minCost(grid, Coord{0, 0}, Coord{len(grid[0])-1, len(grid)-1})
|
||||
})
|
||||
|
||||
challenge.Solution(2, func (input *bufio.Scanner) int {
|
||||
var grid [][]int
|
||||
for y := 0; input.Scan(); y++ {
|
||||
line := input.Text()
|
||||
|
||||
row := make([]int, len(line)*5)
|
||||
|
||||
for i, c := range line {
|
||||
n, _ := strconv.Atoi(string(c))
|
||||
for j := 0; j < 5; j++ {
|
||||
v := n + j
|
||||
if v > 9 {
|
||||
v -= 9
|
||||
}
|
||||
row[i+j*len(line)] = v
|
||||
}
|
||||
}
|
||||
|
||||
grid = append(grid, row)
|
||||
}
|
||||
|
||||
height := len(grid)
|
||||
for j := 1; j < 5; j++ {
|
||||
for y := 0; y < height; y++ {
|
||||
row := make([]int, len(grid[y]))
|
||||
|
||||
for x, n := range grid[y] {
|
||||
v := n + j
|
||||
if v > 9 {
|
||||
v -= 9
|
||||
}
|
||||
row[x] = v
|
||||
}
|
||||
|
||||
grid = append(grid, row)
|
||||
}
|
||||
}
|
||||
|
||||
// printGrid(grid)
|
||||
|
||||
return minCost(grid, Coord{0, 0}, Coord{len(grid[0])-1, len(grid)-1})
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue
Block a user