2021 - Day 9
This commit is contained in:
parent
f7a5965348
commit
3b0f5ab20c
9
2021/9/go.mod
Normal file
9
2021/9/go.mod
Normal file
|
@ -0,0 +1,9 @@
|
|||
module AoC/2021/9
|
||||
|
||||
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/9/go.sum
Normal file
2
2021/9/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=
|
127
2021/9/main.go
Normal file
127
2021/9/main.go
Normal file
|
@ -0,0 +1,127 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
aoc "AoC/2021/common"
|
||||
"bufio"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func processInput(input *bufio.Scanner) ([][]int, int, int) {
|
||||
var heightmap [][]int
|
||||
for input.Scan() {
|
||||
heights := strings.Split(input.Text(), "")
|
||||
|
||||
var row []int
|
||||
for _, height := range heights {
|
||||
// Ignore any errors
|
||||
h, _ := strconv.Atoi(height)
|
||||
row = append(row, h)
|
||||
}
|
||||
|
||||
heightmap = append(heightmap, row)
|
||||
}
|
||||
|
||||
ymax := len(heightmap) - 1
|
||||
// This assumes that at least one row exists and that all rows have the same length
|
||||
xmax := len(heightmap[0]) - 1
|
||||
|
||||
return heightmap, xmax, ymax
|
||||
}
|
||||
|
||||
func floodFill(heightmap [][]int, marked []bool, size int, x int, y int, xmax int, ymax int) ([]bool, int) {
|
||||
if heightmap[y][x] != 9 && !marked[y*(xmax+1) + x] {
|
||||
marked[y*(xmax+1) + x] = true
|
||||
size++
|
||||
|
||||
if (x != 0) {
|
||||
marked, size = floodFill(heightmap, marked, size, x-1, y, xmax, ymax)
|
||||
}
|
||||
|
||||
if (x != xmax) {
|
||||
marked, size = floodFill(heightmap, marked, size, x+1, y, xmax, ymax)
|
||||
}
|
||||
|
||||
if (y != 0) {
|
||||
marked, size = floodFill(heightmap, marked, size, x, y-1, xmax, ymax)
|
||||
}
|
||||
|
||||
if (y != ymax) {
|
||||
marked, size = floodFill(heightmap, marked, size, x, y+1, xmax, ymax)
|
||||
}
|
||||
}
|
||||
|
||||
return marked, size
|
||||
}
|
||||
|
||||
func main() {
|
||||
challenge := aoc.New(2021, 9)
|
||||
|
||||
challenge.Test(`2199943210
|
||||
3987894921
|
||||
9856789892
|
||||
8767896789
|
||||
9899965678`, []int{15, 1134})
|
||||
|
||||
challenge.Solution(1, func (input *bufio.Scanner) int {
|
||||
heightmap, xmax, ymax := processInput(input)
|
||||
|
||||
sum := 0
|
||||
for y := 0; y <= ymax; y++ {
|
||||
for x := 0; x <= xmax; x++ {
|
||||
height := heightmap[y][x]
|
||||
if (x != 0 && heightmap[y][x-1] <= height) || (x != xmax && heightmap[y][x+1] <= height) {
|
||||
// Neighbour on the x-axis is lower
|
||||
continue
|
||||
}
|
||||
|
||||
if (y != 0 && heightmap[y-1][x] <= height) || (y != ymax && heightmap[y+1][x] <= height) {
|
||||
// Neighbour on the y-axis is lower
|
||||
continue
|
||||
}
|
||||
|
||||
// Found a low point
|
||||
sum += 1 + height
|
||||
}
|
||||
}
|
||||
|
||||
return sum
|
||||
})
|
||||
|
||||
challenge.Solution(2, func (input *bufio.Scanner) int {
|
||||
heightmap, xmax, ymax := processInput(input)
|
||||
|
||||
// Find the size of all basins
|
||||
var sizes []int
|
||||
for y := 0; y <= ymax; y++ {
|
||||
for x := 0; x <= xmax; x++ {
|
||||
height := heightmap[y][x]
|
||||
if (x != 0 && heightmap[y][x-1] <= height) || (x != xmax && heightmap[y][x+1] <= height) {
|
||||
// Neighbour on the x-axis is lower
|
||||
continue
|
||||
}
|
||||
|
||||
if (y != 0 && heightmap[y-1][x] <= height) || (y != ymax && heightmap[y+1][x] <= height) {
|
||||
// Neighbour on the y-axis is lower
|
||||
continue
|
||||
}
|
||||
|
||||
// Found a low point, find the size of the basin using flood fill
|
||||
_, size := floodFill(heightmap, make([]bool, (ymax+1)*(xmax+1)), 0, x, y, xmax, ymax)
|
||||
sizes = append(sizes, size)
|
||||
}
|
||||
}
|
||||
|
||||
// Sort the basin sizes
|
||||
sort.Ints(sizes)
|
||||
|
||||
// Multiply the largest three
|
||||
answer := 1
|
||||
for _, size := range sizes[len(sizes)-3:] {
|
||||
answer *= size
|
||||
}
|
||||
|
||||
return answer
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue
Block a user