package main import ( "fmt" "strconv" "strings" "git.mstar.dev/mstar/goutils/other" "git.mstar.dev/mstar/goutils/sliceutils" "git.mstar.dev/mstar/aoc24/util" ) type Map [][]int //Y, X type Coordinate struct { X, Y int } func parseLinesToMap(lines []string) Map { return sliceutils.Map(lines, func(t string) []int { return sliceutils.Map( strings.Split(t, ""), func(t string) int { return other.Must(strconv.Atoi(t)) }, ) }) } func findStartingPositions(area Map) (coords []Coordinate) { coords = []Coordinate{} for iy, line := range area { for ix, height := range line { if height == 0 { coords = append(coords, Coordinate{ix, iy}) } } } return } func (m Map) get(x, y int) int { if y < 0 || y >= len(m) || x < 0 || x >= len(m[0]) { return 0 } return m[y][x] } func findNextValidCoords(area Map, currentLevel int, nextTo Coordinate) (coords []Coordinate) { coords = []Coordinate{} if area.get(nextTo.X+1, nextTo.Y) == currentLevel+1 { coords = append(coords, Coordinate{nextTo.X + 1, nextTo.Y}) } if area.get(nextTo.X-1, nextTo.Y) == currentLevel+1 { coords = append(coords, Coordinate{nextTo.X - 1, nextTo.Y}) } if area.get(nextTo.X, nextTo.Y+1) == currentLevel+1 { coords = append(coords, Coordinate{nextTo.X, nextTo.Y + 1}) } if area.get(nextTo.X, nextTo.Y-1) == currentLevel+1 { coords = append(coords, Coordinate{nextTo.X, nextTo.Y - 1}) } fmt.Printf("Next valid coords for %d at %v: %v\n", currentLevel, nextTo, coords) return } func traverseFromCoord(area Map, start Coordinate) []Coordinate { currentLevel := area[start.Y][start.X] fmt.Printf("Traversing from level %d at %v\n", currentLevel, start) if currentLevel == 9 { fmt.Printf("Hit peak at %v, exiting\n", start) return []Coordinate{start} } nextValidCoords := findNextValidCoords(area, currentLevel, start) if len(nextValidCoords) == 0 { // fmt.Printf("Dead end at %v (%d), exiting\n", start, currentLevel) return []Coordinate{} } ends := []Coordinate{} for _, coord := range nextValidCoords { ends = append(ends, traverseFromCoord(area, coord)...) } return ends } func main() { inputLines := util.FileContentToNonEmptyLines(util.LoadFileFromArgs()) area := parseLinesToMap(inputLines) startingPositions := findStartingPositions(area) // log.Printf("Starting positions: %v\n", startingPositions) // var wg sync.WaitGroup allCollectedEnds := []Coordinate{} allCollectedPaths := []Coordinate{} // addChan := make(chan []Coordinate, 1) // go func() { // for coord := range addChan { // allCollectedEnds = append(allCollectedEnds, coord...) // } // }() // wg.Add(len(startingPositions)) for _, coord := range startingPositions { // go func() { tmp := traverseFromCoord(area, coord) allCollectedEnds = append( allCollectedEnds, sliceutils.RemoveDuplicate(tmp)...) allCollectedPaths = append(allCollectedPaths, tmp...) // wg.Done() // }() } // wg.Wait() // uniqueEnds := sliceutils.RemoveDuplicate(allCollectedEnds) fmt.Printf("Task 1: %d\n", len(allCollectedEnds)) fmt.Printf("Task 2: %d\n", len(allCollectedPaths)) }