Day10
This commit is contained in:
141
2024/gareth/day10/day10.go
Normal file
141
2024/gareth/day10/day10.go
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
package day10
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var directions = [][2]int{
|
||||||
|
{-1, 0},
|
||||||
|
{1, 0},
|
||||||
|
{0, -1},
|
||||||
|
{0, 1},
|
||||||
|
}
|
||||||
|
|
||||||
|
func Part1(input string) int {
|
||||||
|
grid := ParseInput(input)
|
||||||
|
return CalculateTotalTrailheadScore(grid)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Part2(input string) int {
|
||||||
|
grid := ParseInput(input)
|
||||||
|
return CalculateTotalTrailheadRating(grid)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseInput(input string) [][]int {
|
||||||
|
lines := strings.Split(strings.TrimSpace(input), "\n")
|
||||||
|
grid := make([][]int, len(lines))
|
||||||
|
for i, line := range lines {
|
||||||
|
grid[i] = make([]int, len(line))
|
||||||
|
for j, char := range line {
|
||||||
|
grid[i][j] = int(char - '0')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return grid
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsValidPosition(x, y, rows, cols int) bool {
|
||||||
|
return x >= 0 && x < rows && y >= 0 && y < cols
|
||||||
|
}
|
||||||
|
|
||||||
|
func DFS(grid [][]int, x, y, prevHeight int, visited [][]bool, reached9 map[[2]int]bool) {
|
||||||
|
rows := len(grid)
|
||||||
|
cols := len(grid[0])
|
||||||
|
if !IsValidPosition(x, y, rows, cols) || visited[x][y] || grid[x][y] != prevHeight+1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if grid[x][y] == 9 {
|
||||||
|
reached9[[2]int{x, y}] = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
visited[x][y] = true
|
||||||
|
for _, dir := range directions {
|
||||||
|
nx, ny := x+dir[0], y+dir[1]
|
||||||
|
DFS(grid, nx, ny, grid[x][y], visited, reached9)
|
||||||
|
}
|
||||||
|
visited[x][y] = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func CalculateTrailheadScore(grid [][]int, x, y int) int {
|
||||||
|
rows := len(grid)
|
||||||
|
cols := len(grid[0])
|
||||||
|
visited := make([][]bool, rows)
|
||||||
|
for i := range visited {
|
||||||
|
visited[i] = make([]bool, cols)
|
||||||
|
}
|
||||||
|
|
||||||
|
reached9 := make(map[[2]int]bool)
|
||||||
|
DFS(grid, x, y, -1, visited, reached9)
|
||||||
|
return len(reached9)
|
||||||
|
}
|
||||||
|
|
||||||
|
func DFSForRatings(grid [][]int, x, y, prevHeight int, visited [][]bool, trailCache map[[3]int]int) int {
|
||||||
|
rows := len(grid)
|
||||||
|
cols := len(grid[0])
|
||||||
|
if !IsValidPosition(x, y, rows, cols) || visited[x][y] || grid[x][y] != prevHeight+1 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if grid[x][y] == 9 {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
cacheKey := [3]int{x, y, grid[x][y]}
|
||||||
|
if count, exists := trailCache[cacheKey]; exists {
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
|
visited[x][y] = true
|
||||||
|
totalTrails := 0
|
||||||
|
for _, dir := range directions {
|
||||||
|
nx, ny := x+dir[0], y+dir[1]
|
||||||
|
totalTrails += DFSForRatings(grid, nx, ny, grid[x][y], visited, trailCache)
|
||||||
|
}
|
||||||
|
visited[x][y] = false
|
||||||
|
|
||||||
|
trailCache[cacheKey] = totalTrails
|
||||||
|
return totalTrails
|
||||||
|
}
|
||||||
|
|
||||||
|
func CalculateTrailheadRating(grid [][]int, x, y int) int {
|
||||||
|
rows := len(grid)
|
||||||
|
cols := len(grid[0])
|
||||||
|
visited := make([][]bool, rows)
|
||||||
|
for i := range visited {
|
||||||
|
visited[i] = make([]bool, cols)
|
||||||
|
}
|
||||||
|
|
||||||
|
trailCache := make(map[[3]int]int)
|
||||||
|
return DFSForRatings(grid, x, y, -1, visited, trailCache)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CalculateTotalTrailheadScore(grid [][]int) int {
|
||||||
|
rows := len(grid)
|
||||||
|
cols := len(grid[0])
|
||||||
|
totalScore := 0
|
||||||
|
for i := 0; i < rows; i++ {
|
||||||
|
for j := 0; j < cols; j++ {
|
||||||
|
if grid[i][j] == 0 {
|
||||||
|
score := CalculateTrailheadScore(grid, i, j)
|
||||||
|
totalScore += score
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return totalScore
|
||||||
|
}
|
||||||
|
|
||||||
|
func CalculateTotalTrailheadRating(grid [][]int) int {
|
||||||
|
rows := len(grid)
|
||||||
|
cols := len(grid[0])
|
||||||
|
totalRating := 0
|
||||||
|
for i := 0; i < rows; i++ {
|
||||||
|
for j := 0; j < cols; j++ {
|
||||||
|
if grid[i][j] == 0 {
|
||||||
|
rating := CalculateTrailheadRating(grid, i, j)
|
||||||
|
totalRating += rating
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return totalRating
|
||||||
|
}
|
||||||
31
2024/gareth/day10/day10_test.go
Normal file
31
2024/gareth/day10/day10_test.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package day10
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPart1(t *testing.T) {
|
||||||
|
r := Part1(`89010123
|
||||||
|
78121874
|
||||||
|
87430965
|
||||||
|
96549874
|
||||||
|
45678903
|
||||||
|
32019012
|
||||||
|
01329801
|
||||||
|
10456732`)
|
||||||
|
assert.Equal(t, 36, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPart2(t *testing.T) {
|
||||||
|
r := Part2(`89010123
|
||||||
|
78121874
|
||||||
|
87430965
|
||||||
|
96549874
|
||||||
|
45678903
|
||||||
|
32019012
|
||||||
|
01329801
|
||||||
|
10456732`)
|
||||||
|
assert.Equal(t, 81, r)
|
||||||
|
}
|
||||||
45
2024/gareth/day10/input.txt
Normal file
45
2024/gareth/day10/input.txt
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
987123434330121232101001234730123456781067632
|
||||||
|
876076576521010345692340349823212347892398701
|
||||||
|
945087689432105676787659856714503210987445610
|
||||||
|
332196576587654989801456787609654502376530923
|
||||||
|
211543210298923215432321098128778901430121894
|
||||||
|
300692340147210106523543210039569876589836765
|
||||||
|
456781678236103267015693016543410231276745650
|
||||||
|
576890549345234178106782187612320140345654321
|
||||||
|
985098432100125089235493498109876056034765012
|
||||||
|
834127102345456978340362569018765487123876678
|
||||||
|
123236221976347869651251078729034398101985589
|
||||||
|
014545340889298958707867897430120987012834432
|
||||||
|
105965456770107843216950956541231276543124501
|
||||||
|
896872378761016930345441019876501345678023670
|
||||||
|
787901069654325321210332398545432330589012981
|
||||||
|
107821543213034321089206787638901421432103210
|
||||||
|
215430694102123475670115896129876548901210349
|
||||||
|
126989780210014984308924925014578037654321458
|
||||||
|
037878921001235675217833210123669123109452367
|
||||||
|
549865438901045102346542106548754321278501476
|
||||||
|
678954987432696201256430087239689870347699985
|
||||||
|
230143006501787349961021298101236787656788014
|
||||||
|
123272112981010458872787034010345691875107623
|
||||||
|
054387623472129867763698125676210010961234510
|
||||||
|
565694502561036789854567012980387121250129878
|
||||||
|
676783411051045672343218763901296030343278569
|
||||||
|
989872123432345891050109654812345145467303450
|
||||||
|
012763094321056700891760345765432256958912341
|
||||||
|
103450185789763211709851236876301967843211032
|
||||||
|
814321276656854345612345654954101878701208983
|
||||||
|
923434434565956745678036783063210989870345674
|
||||||
|
874532345410345832989123192178981876781456564
|
||||||
|
265101654323234901808765013265432185692387565
|
||||||
|
103216765432101267814554323476501094501893474
|
||||||
|
232109856321011876923601098789678923432102985
|
||||||
|
343898707896540945498712367765672310567891078
|
||||||
|
456789010987231234321203456894581455454986569
|
||||||
|
556776125670102343100157654503490166303890432
|
||||||
|
543895434894321765212348983212321876212761201
|
||||||
|
432104898765010894301054581200110955211654300
|
||||||
|
301256567656987105498765690341034567300563212
|
||||||
|
434567430547896234787654785652123498456767843
|
||||||
|
321798121032345375696543098743096567877854952
|
||||||
|
210899021121036789781232143456787656928923761
|
||||||
|
326765430110145678710123232109876543210010890
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"aoc2024/day19"
|
"aoc2024/day10"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
@@ -9,9 +9,9 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
data, _ := os.ReadFile("day19/input.txt")
|
data, _ := os.ReadFile("day10/input.txt")
|
||||||
fmt.Printf("part 1: %d\n", day19.Part1(string(data)))
|
fmt.Printf("part 1: %d\n", day10.Part1(string(data)))
|
||||||
fmt.Printf("part 2: %d\n", day19.Part2(string(data)))
|
fmt.Printf("part 2: %d\n", day10.Part2(string(data)))
|
||||||
elapsed := time.Since(start)
|
elapsed := time.Since(start)
|
||||||
fmt.Printf("Execution time: %s\n", elapsed)
|
fmt.Printf("Execution time: %s\n", elapsed)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user