Advent of Code: Day 5

Author: Leo Nguyen Dec 5, 2021

There is a list of lines, which are defined by two ending points (coordinates are given to you). Let's say you draw all of them on a grid, can you find the number of points on the grid that have two or more lines through them? Assume only vertical and horizontal lines.

You can read the puzzle here.

This is my solution in Python:

def read(filename):
    file = open(filename)

    x1, y1, x2, y2 = [], [], [], []

    for line in file.read().splitlines():
        items = line.split()
        x1y1 = items[0]
        x2y2 = items[2]

        x1.append(int(x1y1.split(',')[0]))
        y1.append(int(x1y1.split(',')[1]))
        x2.append(int(x2y2.split(',')[0]))
        y2.append(int(x2y2.split(',')[1]))

    return x1, y1, x2, y2


def solve(x1, y1, x2, y2):
    # Create matrix of n x n
    m = max(x1 + x2) + 1
    n = max(y1 + y2) + 1
    a = [[0] * n for i in range(m)]

    # Iterate each line
    for i in range(len(x1)):
        # If same x
        if x1[i] == x2[i]:
            for y in range(min(y1[i], y2[i]), max(y1[i], y2[i]) + 1):
                a[x1[i]][y] += 1

        # If same y
        if y1[i] == y2[i]:
            for x in range(min(x1[i], x2[i]), max(x1[i], x2[i]) + 1):
                a[x][y1[i]] += 1

    # Count where m >= 2
    s = 0
    for row in a:
        s += sum([1 for number in row if number >= 2])

    print(s)


x1, y1, x2, y2 = read('input.txt')
solve(x1, y1, x2, y2)

Part 2 is very similar, only differs in that now let's assume the lines can be diagonal too. To simplify the problem, there are only perfectly 45°-angled lines. Now calculate the number of points that are struck by more than one line.

So my solution is modified as thus:

def read(filename):
    file = open(filename)

    x1, y1, x2, y2 = [], [], [], []

    for line in file.read().splitlines():
        items = line.split()
        point1 = items[0]
        point2 = items[2]

        x1.append(int(point1.split(',')[0]))
        y1.append(int(point1.split(',')[1]))
        x2.append(int(point2.split(',')[0]))
        y2.append(int(point2.split(',')[1]))

    return x1, y1, x2, y2


def solve(x1, y1, x2, y2):
    # Create matrix of n x n
    m = max(x1 + x2) + 1
    n = max(y1 + y2) + 1
    a = [[0] * n for i in range(m)]

    # Iterate each line
    for i in range(len(x1)):
        # Fill the matrix with points in between
        xstep = 0 if x2[i] == x1[i] else 1 if x2[i] > x1[i] else -1
        ystep = 0 if y2[i] == y1[i] else 1 if y2[i] > y1[i] else -1

        x, y = x1[i], y1[i]

        while True:
            a[x][y] += 1
            x += xstep
            y += ystep

            if x == x2[i] and y == y2[i]:
                a[x][y] += 1
                break

    # Count where m >= 2
    s = 0
    for row in a:
        s += sum([1 for number in row if number >= 2])

    print(s)


x1, y1, x2, y2 = read('input.txt')
solve(x1, y1, x2, y2)