From b17c80d1dda721f1b70af1e243403228651eb06b Mon Sep 17 00:00:00 2001 From: Gregory Date: Mon, 21 Feb 2022 22:01:00 +0200 Subject: [PATCH] d9 --- d9/d9.go | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++ d9/d9_test.go | 27 +++++++++++++ main.go | 3 ++ 3 files changed, 135 insertions(+) create mode 100644 d9/d9.go create mode 100644 d9/d9_test.go diff --git a/d9/d9.go b/d9/d9.go new file mode 100644 index 0000000..0ce64fd --- /dev/null +++ b/d9/d9.go @@ -0,0 +1,105 @@ +package d9 + +import ( + "fmt" + "sort" + "strconv" + "strings" +) + +func bigger(a byte, b byte) bool { + aNum, _ := strconv.Atoi(string(a)) + bNum, _ := strconv.Atoi(string(b)) + + return aNum > bNum +} + +func toNum(str byte) int { + num, _ := strconv.Atoi(string(str)) + return num +} + +func addWalls(lines []string) []string { + for i, line := range lines { + lines[i] = fmt.Sprintf("9%v9", line) + } + + nines := strings.Repeat("9", len(lines[0])) + return append([]string{nines}, append(lines, nines)...) +} + +func D9(in string) int { + lines := addWalls(strings.Split(strings.TrimSpace(in), "\n")) + risk := 0 + + for i := 1; i < len(lines)-1; i++ { + for j := 1; j < len(lines[0])-1; j++ { + current := lines[i][j] + top := bigger(lines[i-1][j], current) + right := bigger(lines[i][j+1], current) + bottom := bigger(lines[i+1][j], current) + left := bigger(lines[i][j-1], current) + if top && right && bottom && left { + risk += toNum(current) + 1 + } + } + } + + return risk +} + +type exists struct{} + +type pos struct { + x int + y int +} + +type basin map[pos]exists + +const wall = '9' + +func flooded(x, y int, basins []basin) bool { + for _, basin := range basins { + if _, ok := basin[pos{x, y}]; ok { + return true + } + } + + return false +} + +func flood(x, y int, heights []string, basin basin) basin { + if heights[y][x] == wall { + return basin + } + + if _, ok := basin[pos{x, y}]; ok { + return basin + } + + basin[pos{x, y}] = exists{} + + flood(x, y-1, heights, basin) + flood(x+1, y, heights, basin) + flood(x, y+1, heights, basin) + flood(x-1, y, heights, basin) + return basin +} + +func D9P2(in string) int { + heights := addWalls(strings.Split(strings.TrimSpace(in), "\n")) + basins := []basin{} + + for y := 1; y < len(heights)-1; y++ { + for x := 1; x < len(heights[0])-1; x++ { + if !flooded(x, y, basins) && heights[y][x] != wall { + basins = append(basins, flood(x, y, heights, basin{})) + } + } + } + + sort.Slice(basins, func(i, j int) bool { return len(basins[i]) > len(basins[j]) }) + + return len(basins[0]) * len(basins[1]) * len(basins[2]) +} diff --git a/d9/d9_test.go b/d9/d9_test.go new file mode 100644 index 0000000..5d1e391 --- /dev/null +++ b/d9/d9_test.go @@ -0,0 +1,27 @@ +package d9 + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestD8(t *testing.T) { + input := `2199943210 +3987894921 +9856789892 +8767896789 +9899965678` + + assert.EqualValues(t, 15, D9(input)) +} + +func TestD8P2(t *testing.T) { + input := `2199943210 +3987894921 +9856789892 +8767896789 +9899965678` + + assert.EqualValues(t, 1134, D9P2(input)) +} diff --git a/main.go b/main.go index 34c79b1..c678ae0 100644 --- a/main.go +++ b/main.go @@ -15,6 +15,7 @@ import ( "github.com/fotonmoton/aoc2021/d6" "github.com/fotonmoton/aoc2021/d7" "github.com/fotonmoton/aoc2021/d8" + "github.com/fotonmoton/aoc2021/d9" ) func main() { @@ -43,4 +44,6 @@ func main() { fmt.Printf("day 7 part 2: %v\n", d7.D7P2(client.Day(7))) fmt.Printf("day 8: %v\n", d8.D8(client.Day(8))) fmt.Printf("day 8 part 2: %v\n", d8.D8P2(client.Day(8))) + fmt.Printf("day 9: %v\n", d9.D9(client.Day(9))) + fmt.Printf("day 9 part 2: %v\n", d9.D9P2(client.Day(9))) }