@@ 14,66 14,44 @@ type listOrInt struct {
lst []listOrInt
}
-func (n listOrInt) String() string {
- s := ""
- if n.isList {
- s += "["
- for i, e := range n.lst {
- s += e.String()
- if i+1 < len(n.lst) {
- s += ","
- }
- }
- s += "]"
- } else {
- s = fmt.Sprintf("%d", n.num)
- }
- return s
-}
-
-func readList(s string, start int) (listOrInt, int) {
+func readList(s string, mark int) (listOrInt, int) {
isList, num, lst := false, 0, []listOrInt{}
- if s[start] == byte('[') {
+ if s[mark] == byte('[') {
isList = true
- start++
- for s[start] != byte(']') {
- if s[start] == byte(',') {
- start++
+ mark++
+ for s[mark] != byte(']') {
+ if s[mark] == byte(',') {
+ mark++
}
- next, end := readList(s, start)
+ next, end := readList(s, mark)
lst = append(lst, next)
- start = end
+ mark = end
}
- start++
+ mark++
} else {
- i := start
+ i := mark
for ; s[i] != byte(',') && s[i] != byte(']'); i++ {
}
- if val, err := strconv.Atoi(s[start:i]); err == nil {
+ if val, err := strconv.Atoi(s[mark:i]); err == nil {
num = val
} else {
panic(err)
}
- start = i
+ mark = i
}
- return listOrInt{isList, num, lst}, start
+ return listOrInt{isList, num, lst}, mark
}
func compare(left listOrInt, right listOrInt) int {
if !left.isList && !right.isList {
return left.num - right.num
} else if left.isList && right.isList {
- for i := 0; i < len(left.lst) || i < len(right.lst); i++ {
- if i < len(left.lst) && i < len(right.lst) {
- if x := compare(left.lst[i], right.lst[i]); x != 0 {
- return x
- }
- } else if i >= len(left.lst) && i < len(right.lst) {
- return -1
- } else if i < len(left.lst) && i >= len(right.lst) {
- return 1
+ for i := 0; i < len(left.lst) && i < len(right.lst); i++ {
+ if x := compare(left.lst[i], right.lst[i]); x != 0 {
+ return x
}
}
+ return len(left.lst) - len(right.lst)
} else if left.isList && !right.isList {
if x := compare(left, listOrInt{true, 0, []listOrInt{right}}); x != 0 {
return x
@@ 100,10 78,9 @@ func main() {
panic(err)
}
lines := strings.Split(string(input), "\n")
- part1 := 0
+ part1, part2 := 0, []int{1, 1}
div2, _ := readList("[[2]]", 0)
div6, _ := readList("[[6]]", 0)
- part2 := []int{1, 1}
for i := 0; i < len(lines); i += 3 {
index, a, b := (i+1)/3+1, i, i+1
left, _ := readList(lines[a], 0)
@@ 111,15 88,13 @@ func main() {
if compare(left, right) < 1 {
part1 += index
}
- if compare(left, div2) < 1 {
- part2[0]++
- } else if compare(left, div6) < 1 {
- part2[1]++
- }
- if compare(right, div2) < 1 {
- part2[0]++
- } else if compare(right, div6) < 1 {
- part2[1]++
+ listOrInts := []listOrInt{left, right}
+ for _, loi := range listOrInts {
+ if compare(loi, div2) < 1 {
+ part2[0]++
+ } else if compare(loi, div6) < 1 {
+ part2[1]++
+ }
}
}