Sean McLemon | Advent of Code

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


2021-12-10 - Syntax Scoring

(original .ipynb)

Day 10 puzzle input is a sequence of lines comprising different types of brackets - parentheses, curly braces, square brackets and curly braces (mine is here). Part 1 involves validating whether the closing bracket for each opening one - if there is an error we return report an error score and collect the total. Part 2 involves finding the valid sequences, determining the string that would complete each one, calculating a score for this additional string, sorting these scores and taking the middle one.

puzzle_input_str = open("puzzle_input/day10.txt").read()

test_input_str = """[({(<(())[]>[[{[]{<()<>>
[(()[<>])]({[<{<<[]>>(
{([(<{}[<>[]}>{[]{[(<()>
(((({<>}<{<{<>}{[]{[]{}
[[<[([]))<([[{}[[()]]]
[{[{({}]{}}([{[{{{}}([]
{<[[]]>}<{[{[{[]{()[[[]
[<(<(<(<{}))><([]([]()
<{([([[(<>()){}]>(<<{{
<{([{{}}[<[[[<>{}]]]>[]]"""

opener = {
    "(": ")",
    "[": "]",
    "{": "}",
    "<": ">"
}

error = {
    ")": 3,
    "]": 57,
    "}": 1197,
    ">": 25137
}


def parse_input(input_str):
    return [list(line) for line in input_str.split("\n")]


def validate(line):
    stack = []
           
    for c in line:
        if c in opener:
            stack.append(opener[c])
        else:
            expected = stack.pop()
            if expected != c:
                return error[c], None
        
    return 0, stack
    

def part_one(input_str):
    total_score = 0
    for line in parse_input(input_str):
        score, _ = validate(line)
        total_score += score
    
    return total_score


assert 26397 == part_one(test_input_str)
print("part one:", part_one(puzzle_input_str))
part one: 167379
completion_score = {
    ")": 1,
    "]": 2,
    "}": 3,
    ">": 4
}


def part_two(input_str):
    all_scores = []
    for line in parse_input(input_str):
        score, remaining = validate(line)
        if score == 0:
            for c in reversed(remaining):
                score *= 5
                score += completion_score[c]
        
            all_scores.append(score)
    
    return list(sorted(all_scores))[len(all_scores) // 2]


assert 288957 == part_two(test_input_str)
print("part two:", part_two(puzzle_input_str))
part two: 2776842859