#!/usr/bin/env python3 import sys from operator import mul from functools import reduce def adj(mp, x, y): adj = {} if x-1 > -1: adj[(-1,0)] = mp[x-1][y] if x+1 < len(mp): adj[(1,0)] = mp[x+1][y] if y-1 > -1: adj[(0,-1)] = mp[x][y-1] if y+1 < len(mp[0]): adj[(0,1)] = mp[x][y+1] return adj def risk(mp, x, y): ad = adj(mp, x, y).values() if all(map(lambda i: i > mp[x][y], ad)): bas[(x,y)] = 0 return mp[x][y] + 1 else: return 0 def basin(mp, x, y): nex = min(adj(mp, x, y).items(), key=lambda i: i[1]) if (x,y) in bas: (i,j) = (x,y) elif (x,y) in mem: (i,j) = mem[(x,y)] else: (i,j) = basin(mp, x+nex[0][0], y+nex[0][1]) return (i,j) bas[(i,j)] += 1 return (i,j) if __name__ == '__main__': m = [[int(i) for i in l] for l in open(sys.argv[1]).read().strip('\n\n').split('\n')] bas,mem = {},{} # challenge 1 res1 = str(sum([sum([risk(m, x, y) for y in range(len(m[0]))]) for x in range(len(m))])) print("challenge 1:" +"\n" + res1 + "\n") # challenge 2 ([([basin(m, x, y) for y in range(len(m[0])) if m[x][y] < 9]) for x in range(len(m))]) res2 = str(reduce(mul, sorted(bas.values(), reverse=True)[0:3])) print("challenge 2:" +"\n" + res2 + "\n")