Sean McLemon | Advent of Code

Home | Czech | Blog | GitHub | Advent Of Code | Notes


2022-12-13 - Distress Signal

(original .ipynb)

Day 13 puzzle input is a set of pairs os nested lists of numbers, sometimes empty (mine is here). Part 1 involves performing a weird calculation to determine how many of each pair is in the "right order". Part 2 involves ignoring the idea that they're "pairs", including a couple of additional sets, sorting them and multiplying the position where these marker sets end up.

puzzle_input_str = open("./puzzle_input/day13.txt").read()
test_input_str = open("./test_input/day13.txt").read()

wrong_order = 0
right_order = 1
no_decision = 2


def listify(item):
    if type(item) == list:
        return item
    return [item]


def compare_lists(left, right):
    while len(left) > 0 and len(right) > 0:
        l = left.pop(0)
        r = right.pop(0)
        res = compare(l, r)
        if res != no_decision:
            return res
    
    if len(left) == 0 and len(right) == 0:
        return no_decision
    elif len(left) < len(right):
        return right_order
    else:
        return wrong_order

    
def compare(l, r):
    if type(l) == int and type(r) == int:
        if l == r:
            return no_decision
        elif l < r:
            return right_order
        else:
            return wrong_order
    else:
        return compare_lists(listify(l), listify(r))
        

def part_one(input_str):
    pairs = input_str.split("\n\n")
    count = 0
    
    for i, pair in enumerate(pairs):
        left_str, right_str = pair.split("\n")
        res = compare(eval(left_str), eval(right_str))
        if res != wrong_order:
            count += (1+i)

    return count


assert 13 == part_one(test_input_str)

print("part one:", part_one(puzzle_input_str))
part one: 5013
from functools import cmp_to_key, reduce
from copy import deepcopy


def cmp_packet(packet1, packet2):
    return -1 if compare(eval(packet1), eval(packet2)) == wrong_order else 1

        
def part_two(input_str):
    divider_packets = ["[[2]]", "[[6]]"]
    packets = [line for line in input_str.splitlines() if line.strip() != ""] + divider_packets
    
    return reduce(lambda x,y: x*y, [
        1+i 
        for i, packet 
        in enumerate(sorted(packets, key=cmp_to_key(cmp_packet), reverse=True))
        if packet in divider_packets
    ])


assert 140 == part_two(test_input_str)

print("part two:", part_two(puzzle_input_str))
part two: 25038