Skip to content
advent of code 2022

day 13

distress signal

approach

each packet is parsed with eval, since the lines are already valid python lists. compare walks two lists side by side and returns -1, 0 or 1: two ints compare directly, two lists recurse, and a lone int is wrapped in a list before recursing. if one list runs out first, it's the smaller.

part 1 sums the indices of the pairs that compare as ordered. part 2 throws all the packets plus the two divider packets into one list, sorts it with cmp_to_key(compare), and multiplies the dividers' positions.

the trick

once the comparator returns -1/0/1, cmp_to_key turns it into a sort key and part 2 is a plain sort.

python
# p1
print(sum(i for i, ps in enumerate(pairs, 1) if compare(*ps) < 0))

# p2
l = [pp for p in pairs for pp in p] + [[[2]], [[6]]]
s = sorted(l, key = cmp_to_key(compare))
print((s.index([[2]]) + 1) * (s.index([[6]]) + 1))