Skip to content

Commit d370145

Browse files
committed
2022 day 13
1 parent 362c1bd commit d370145

File tree

3 files changed

+627
-0
lines changed

3 files changed

+627
-0
lines changed

2022/go/day13/day13.go

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"os"
7+
"reflect"
8+
"sort"
9+
"strings"
10+
)
11+
12+
func main() {
13+
input, _ := os.ReadFile("../../input/day13.txt")
14+
pairs := readPairs(string(input))
15+
16+
packets := [][]any{}
17+
sum := 0
18+
for i, pair := range pairs {
19+
if less(pair[0], pair[1]) {
20+
sum += i + 1
21+
}
22+
packets = append(packets, pair[0], pair[1])
23+
}
24+
fmt.Printf("part1: %v\n", sum)
25+
26+
packets = append(packets, dividers...)
27+
sort.Sort(ByPacket(packets))
28+
var key int
29+
for i, p := range packets {
30+
if reflect.DeepEqual(p, dividers[0]) {
31+
key = i + 1
32+
} else if reflect.DeepEqual(p, dividers[1]) {
33+
key = key * (i + 1)
34+
}
35+
}
36+
fmt.Printf("part2: %v\n", key)
37+
}
38+
39+
func less(left []any, right []any) (less bool) {
40+
return compare(left, right, 0) <= 0
41+
}
42+
43+
func compare(left []any, right []any, i int) (res int) {
44+
if i >= len(left) && i >= len(right) {
45+
return 0 // end of both lists
46+
} else if i >= len(left) {
47+
return -1 // left ended first
48+
} else if i >= len(right) {
49+
return 1 // right shorter
50+
}
51+
52+
// number comparison
53+
li, ri := left[i], right[i]
54+
ln, isln := li.(float64)
55+
rn, isrn := ri.(float64)
56+
if isln && isrn && ln == rn {
57+
return compare(left, right, i+1) // same, continue to next item
58+
} else if isln && isrn {
59+
return int(ln - rn) // different numbers
60+
}
61+
62+
// list comparison
63+
llist, isllist := li.([]any)
64+
rlist, isrlist := ri.([]any)
65+
if !isllist {
66+
llist = []any{ln} // mixed, convert to list
67+
}
68+
if !isrlist {
69+
rlist = []any{rn} // mixed, convert to list
70+
}
71+
res = compare(llist, rlist, 0)
72+
if res == 0 { // tie, continue to next item
73+
return compare(left, right, i+1)
74+
}
75+
return res
76+
}
77+
78+
var dividers = [][]any{{[]any{float64(2)}}, {[]any{float64(6)}}}
79+
80+
type ByPacket [][]any
81+
82+
func (p ByPacket) Len() int { return len(p) }
83+
func (p ByPacket) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
84+
func (p ByPacket) Less(i, j int) bool { return less(p[i], p[j]) }
85+
86+
func readPairs(input string) (res [][2][]any) {
87+
pairs := strings.Split(input, "\n\n")
88+
for _, pair := range pairs {
89+
part := strings.Split(pair, "\n")
90+
var left, right []any
91+
json.Unmarshal([]byte(part[0]), &left)
92+
json.Unmarshal([]byte(part[1]), &right)
93+
pair := [2][]any{left, right}
94+
res = append(res, pair)
95+
}
96+
return res
97+
}

0 commit comments

Comments
 (0)