hmap = {} with open("input.txt") as f: lines = f.read().split('\n') height = len(lines) width = len(lines[0]) for i, line in enumerate(lines): for j, n in enumerate(line): hmap[(i,j)] = int(n) def adjacent(i,j): adjacent = [ (i-1,j), (i+1,j), (i,j-1), (i,j+1) ] return [ (i,j) for (i,j) in adjacent if (-1 < i < height) and (-1 < j < width) ] # part 1 lowpoints = [] for i in range(height): for j in range(width): current = hmap[(i,j)] neighbors = [hmap[(x,y)] for (x,y) in adjacent(i,j)] if current < min(neighbors): lowpoints.append(current) risk = 0 for h in lowpoints: risk += (h + 1) print(risk) # part 2 basins = [] allpoints = set( [ (i,j) for i in range(height) for j in range(width) ] ) def which_basin(i,j,hmap): """ Identifies the basin that (i,j) is part of. """ basin = set() visited = set() q = [(i,j)] while q: (x, y) = q.pop() if (x,y) not in visited: visited.add((x,y)) if hmap[(x,y)] != 9: basin.add((x,y)) neighbors = [] q += [(m,n) for (m,n) in adjacent(x,y) if (m,n) not in visited] return basin identified = set() for i in range(height): for j in range(width): if (i,j) not in identified: basin = which_basin(i,j,hmap) for point in basin: identified.add(point) basins.append(basin) three_biggest_basins = sorted([len(basin) for basin in basins], reverse=True)[0:3] from math import prod part2 = prod(three_biggest_basins) print(part2)