summaryrefslogtreecommitdiff
path: root/2022/day14.go
blob: 274ff95036397e87dd94b6c5134ba4aab93261a5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
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)
	}
}