DEV Community

Cover image for Advent of Code 2023 - December 3rd
Rob van der Leek
Rob van der Leek

Posted on

Advent of Code 2023 - December 3rd

In this series, I'll share my progress with the 2023 version of Advent of Code.

Check the first post for a short intro to this series.

You can also follow my progress on GitHub.

December 3rd

The puzzle of day 3 was quite some work. It wasn't hard to think of a solution but I needed a lot of code. I tried to reuse as much code as possible between the first and second parts, but in the end main.py is still 68 lines long.

My pitfall for this puzzle: I needed too much code, and of course that increases the risks of nasty bugs πŸ›. I made a typo somewhere and because unit-tests and type-hints are lacking that cost me 30 minutes of hair-pulling debugging.

Solution here, do not click if you want to solve the puzzle first yourself
#!/usr/bin/env python3

with open('input.txt') as infile:
    lines = [line.strip() for line in infile.readlines()]

grid = []
for line in lines:
    grid.append([c for c in line])

def get_row_numbers(row):
    result = []
    cur_index = 0
    cur_number = None
    for i, c in enumerate(row): 
        if c.isdigit():
            if cur_number is None:
                cur_index = i
                cur_number = str(c)
            else:
                cur_number += str(c)
        else:
            if cur_number:
                result.append((cur_index, int(cur_number)))
                cur_number = None
    if cur_number: 
        result.append((cur_index, int(cur_number)))
    return result

def is_symbol(grid, x, y):
    if y < 0 or y > len(grid) - 1:
        return False 
    if x < 0 or x > len(grid[y]) - 1:
        return False
    return grid[y][x] != '.' and not grid[y][x].isdigit()

def get_neighbours(x, y, number):
    num_len = len(str(number))
    return [(x - 1, y), (x + num_len, y)] + \
        [(i, y - 1) for i in range(x - 1, x + num_len + 1)] + \
        [(i, y + 1) for i in range(x - 1, x + num_len + 1)]

def are_neighbours(number_x, number_y, number, x, y):
    return (x, y) in get_neighbours(number_x, number_y, number)

numbers = []
for y, row in enumerate(grid):
    for x, number in get_row_numbers(row):
        for n in get_neighbours(x, y, number):
            if is_symbol(grid, n[0], n[1]):
                numbers.append(number)
print(sum(numbers))

ratios = []
for y, row in enumerate(grid):
    for x, c in enumerate(row):
        if c == '*':
            numbers = []
            if y > 0:
                numbers.extend([n for n_x, n in get_row_numbers(grid[y - 1])
                    if are_neighbours(n_x, y - 1, n, x, y)])
            numbers.extend([n for n_x, n in get_row_numbers(row) 
                if are_neighbours(n_x, y, n, x, y)])
            if y < len(grid) - 1:
                numbers.extend([n for n_x, n in get_row_numbers(grid[y + 1])
                    if are_neighbours(n_x, y + 1, n, x, y)])
            if len(numbers) == 2:
                ratios.append(numbers[0] * numbers[1])
print(sum(ratios))
Enter fullscreen mode Exit fullscreen mode

That's it! See you again tomorrow!

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

Top comments (0)

Sentry image

See why 4M developers consider Sentry, β€œnot bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

πŸ‘‹ Kindness is contagious

Please leave a ❀️ or a friendly comment on this post if you found it helpful!

Okay