-
Notifications
You must be signed in to change notification settings - Fork 0
/
19b.go
126 lines (113 loc) · 2.94 KB
/
19b.go
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// go run 19b.go
package main
import (
"fmt"
"slices"
"strconv"
"strings"
)
type Rule struct {
category int
bound int
less bool
verdict string
}
func parseRule(text string) Rule {
colon := strings.Index(text, ":")
if colon == -1 {
return Rule{0, 0, false, text}
}
category := 0
switch text[0:1] {
case "m": category = 1
case "a": category = 2
case "s": category = 3
}
verdict := text[colon + 1:]
bound, _ := strconv.Atoi(text[2:colon])
less := true
if text[1] == '>' {
less = false
bound += 1
}
return Rule{category, bound, less, verdict}
}
func traverse(workflows map[string][]Rule, xmas *[4]int) bool {
cur := "in"
for {
for _, rule := range workflows[cur] {
value := xmas[rule.category]
if (rule.less && value < rule.bound) || (!rule.less && value >= rule.bound) {
cur = rule.verdict
break
}
}
if cur == "A" { return true }
if cur == "R" { return false }
}
}
func solve(data []string) int {
workflows := map[string][]Rule{}
for _, line := range data {
brace := strings.Index(line, "{")
rules := []Rule{}
for _, text := range strings.Split(line[brace + 1 : (len(line) - 1)], ",") {
rules = append(rules, parseRule(text))
}
workflows[line[0:brace]] = rules
}
boundsMap := map[int]map[int]bool{}
for cat := 0; cat < 4; cat++ {
boundsMap[cat] = map[int]bool{}
boundsMap[cat][1] = true
boundsMap[cat][4001] = true
}
for _, rules := range workflows {
for _, rule := range rules {
if rule.bound > 0 {
boundsMap[rule.category][rule.bound] = true
}
}
}
bounds := map[int][]int{}
for cat := 0; cat < 4; cat++ {
bounds[cat] = []int{}
for number, _ := range boundsMap[cat] {
bounds[cat] = append(bounds[cat], number)
}
slices.Sort(bounds[cat])
}
result := 0
bx := bounds[0]
bm := bounds[1]
ba := bounds[2]
bs := bounds[3]
xmas := [4]int{0, 0, 0, 0}
for ix, vx := range bx[:len(bx) - 1] {
xmas[0] = vx
for im, vm := range bm[:len(bm) - 1] {
xmas[1] = vm
for ia, va := range ba[:len(ba) - 1] {
xmas[2] = va
d := (bx[ix + 1] - vx) * (bm[im + 1] - vm) * (ba[ia + 1] - va)
for is, vs := range bs[:len(bs) - 1] {
xmas[3] = vs
if traverse(workflows, &xmas) {
result += d * (bs[is + 1] - vs)
}
}
}
}
}
return result
}
func main() {
var data = []string{}
var line string
for {
_, err := fmt.Scanln(&line)
if err != nil { break }
data = append(data, line)
}
fmt.Println(solve(data))
}