package main import ( "bufio" "fmt" "log" "os" "strconv" "strings" ) func min(x, y int) int { if x < y { return x } return y } func max(x, y int) int { if x > y { return x } return y } func add_sand(g map[[2]int]int, part int, max_y int, y int, x int) map[[2]int]int { if part == 1 && y > max_y { return g } else if part == 2 && (y == (max_y + 1)) { g[[2]int{y, x}] = 1 return g } else if _, exists := g[[2]int{y + 1, x}]; !exists { return add_sand(g, part, max_y, y+1, x) } else if _, exists := g[[2]int{y + 1, x - 1}]; !exists { return add_sand(g, part, max_y, y+1, x-1) } else if _, exists := g[[2]int{y + 1, x + 1}]; !exists { return add_sand(g, part, max_y, y+1, x+1) } else { g[[2]int{y, x}] = 1 return g } } func main() { // filename := "in/day14.ref" filename := "in/day14.pzl" file, err := os.Open(filename) if err != nil { log.Fatal(err) } defer file.Close() g := map[[2]int]int{} scanner := bufio.NewScanner(file) for scanner.Scan() { line := scanner.Text() path := strings.Split(line, " -> ") xy := strings.Split(path[0], ",") xs, _ := strconv.Atoi(xy[0]) ys, _ := strconv.Atoi(xy[1]) for i := 1; i < len(path); i++ { xy = strings.Split(path[i], ",") xe, _ := strconv.Atoi(xy[0]) ye, _ := strconv.Atoi(xy[1]) for x := min(xs, xe); x < max(xs, xe)+1; x++ { for y := min(ys, ye); y < max(ys, ye)+1; y++ { g[[...]int{y, x}] = 1 } } xs = xe ys = ye } } if err := scanner.Err(); err != nil { log.Fatal(err) } // fmt.Println(g) // fmt.Println(len(g)) var max_y int = 0 for key, _ := range g { if key[0] > max_y { max_y = key[0] } } // fmt.Println("max_y:", max_y) for _, part := range []int{1, 2} { gdup := map[[2]int]int{} for k, v := range g { gdup[k] = v } var start_len int = len(gdup) for { var prev_len int = len(gdup) gdup = add_sand(gdup, part, max_y, 0, 500) if prev_len == len(gdup) { break } } fmt.Println(len(gdup) - start_len) } }