## DEV Community 👩‍💻👨‍💻

Yuan Gao

Posted on • Updated on

# Advent of Code 2021: Day 05 with Python, even more numpy

This time, there's no shortcuts to loading data, it's regex time. The data is a pair of coordinates, and an arrow, and then another pair of coordinates:

``````578,391 -> 578,322
274,585 -> 651,962
482,348 -> 294,348
``````

We can read this in using regex pattern `(\d+),(\d+) -> (\d+),(\d+)`. We also grab the max bounds of the coordinates as well.

``````lines = open("day_5.txt").readlines()
coords = np.array([re.match('(\d+),(\d+) -> (\d+),(\d+)', line).groups() for line in lines]).astype(int)
size = np.max(coords)+1
``````

## Part 1

Part 1 asks us to draw these lines on the grid, and find out how many lines overlap. It also asks us to only consider horizontal and vertical lines.

Horizontal and vertical lines are characterized by having x or y coordinates equal, so we can filter those out:

``````hv = coords[(coords[:, 0] == coords[:, 2]) | (coords[:, 1] == coords[:, 3])]
``````

Then for each of these, we increment the specific indices of the array that they cover:

``````def rrange(start, stop):
return range(start, stop+1) if stop >= start else range(start, stop-1, -1)

grid = np.zeros((size, size))
for x1, y1, x2, y2 in hv:
grid[rrange(y1, y2), rrange(x1, x2)] += 1
result = (grid >= 2).sum()
``````

The `rrange()` function is a small helper to allow `range()` to run backwards properly. Because `range(1, 5)` works fine, but `range(5, 1)` does not unless specifying the step size as -1 with `range(5, 1, -1)`. The coordinates are also adjusted to make the values inclusive.

Once the grid values have been incremented, we can find all the grid elements with values greater or equal to 2, giving the answer.

## Part 2

Part 2 asks us to look at not just horizontal and vertical lines, but also diagonal ones. Oddly, we already wrote the code in a way that's general, so no extra code is needed, we just iterate over the original unfiltered coordinates rather than the ones filtered for only horizontal/vertical lines

``````grid = np.zeros((size, size))
for x1, y1, x2, y2 in coords:
grid[rrange(y1, y2), rrange(x1, x2)] += 1
result = (grid >= 2).sum()
``````

## Full code

``````import numpy as np
import re

coords = np.array([re.match('(\d+),(\d+) -> (\d+),(\d+)', line).groups() for line in lines]).astype(int)
size = np.max(coords)+1

def rrange(start, stop):
return range(start, stop+1) if stop >= start else range(start, stop-1, -1)

grid = np.zeros((size, size))
hv = coords[(coords[:, 0] == coords[:, 2]) | (coords[:, 1] == coords[:, 3])]
for x1, y1, x2, y2 in hv:
grid[rrange(y1, y2), rrange(x1, x2)] += 1
result = (grid >= 2).sum()
print("Part 1 result:", result)

grid = np.zeros((size, size))
for x1, y1, x2, y2 in coords:
grid[rrange(y1, y2), rrange(x1, x2)] += 1
result = (grid >= 2).sum()
print("Part 2 result:", result)
`````` Hi.
It is quite unclear why you use this condition with '+' in between when filtering the coordinates.

hv = coords[(coords[:, 0] == coords[:, 2]) + (coords[:, 1] == coords[:, 3])]

Do you care to elaborate a bit more? :D Also, how else would this be implemented, using maybe more lines of code? Yuan Gao

the '+' does an addition, admittedly that should have been an `|` instead to be more clear. I have edited the article

coords[:, 0] == coords[:, 2] generates a list that is True if the x values are the same and False otherwise
coords[:, 1] == coords[:, 3] generates a list that is True if the y values are the same and False otherwise

so (coords[:, 0] == coords[:, 2]) + (coords[:, 1] == coords[:, 3]) adds those together, so the result is True if either of the two conditions are true. I should have used `|` to do an OR operation instead. Though the result is the same.

Longer code could look like:

``````x_same_indexes = coords[:, 0] == coords[:, 2]
y_same_indexes = coords[:, 1] == coords[:, 3]

hv_indexes = x_same_indexes | y_same_indexes
hv = coords[hv_indexes]
``````

## Let's Get Wacky Use any Linode offering to create something unique or silly in the DEV x Linode Hackathon 2022 and win the Wacky Wildcard category

Join the Hackathon <-