Day 13 - Advent of Code 2022

Working solutions for the day 13 puzzles.

Part One

""" day_13_01.py """

# usage: python3 day_13_01.py < input


from itertools import zip_longest


def compare(left_item, right_item):
    """ using rules of puzzle - compare """
    for i, j in zip_longest(left_item, right_item):
        if i is None:
            return True
        if j is None:
            return False
        if isinstance(i, int) and isinstance(j, int):
            if i < j:
                return True
            if i > j:
                return False
            continue
        if isinstance(i, list) and isinstance(j, list):
            v, w = i, j
        elif isinstance(i, int) and isinstance(j, list):
            v, w = [i], j
        elif isinstance(i, list) and isinstance(j, int):
            v, w = i, [j]
        if (status := compare(v, w)) is not None:
            return status
    return None


total = 0
index = 1
while True:
    left, right = input(), input()
    if compare(eval(left), eval(right)):
        total += index
    try:
        input()
    except EOFError:
        break
    else:
        index += 1
print(total)

Part Two

""" day_13_02.py """

# usage: python3 day_13_02.py < input


import sys
from functools import cmp_to_key
from itertools import zip_longest


def compare(left_item, right_item):
    """ using rules of puzzle - compare """
    for i, j in zip_longest(left_item, right_item):
        if i is None:
            return True
        if j is None:
            return False
        if isinstance(i, int) and isinstance(j, int):
            if i < j:
                return True
            if i > j:
                return False
            continue
        if isinstance(i, list) and isinstance(j, list):
            v, w = i, j
        elif isinstance(i, int) and isinstance(j, list):
            v, w = [i], j
        elif isinstance(i, list) and isinstance(j, int):
            v, w = i, [j]
        if (status := compare(v, w)) is not None:
            return status
    return None


def compare_wrapper(left_item, right_item):
    """ wrap compare for cmp_to_key function """
    value = {True: -1, False: 1, None: 0}
    return value[compare(left_item, right_item)]


packets = [packet for packet in sys.stdin.read().splitlines() if packet != '']
packets = [eval(packet) for packet in packets + ['[[2]]'] + ['[[6]]']]

packets.sort(key=cmp_to_key(compare_wrapper))
print((packets.index([[2]]) + 1) * (packets.index([[6]]) + 1))