···11+import fileinput
22+from utils import mul
33+44+DIRS = [
55+ (0, 1),
66+ (0, -1),
77+ (-1, 0),
88+ (1, 0),
99+]
1010+1111+# Parse problem input.
1212+grid = {}
1313+for y, line in enumerate(fileinput.input()):
1414+ for x, c in enumerate(line.strip()):
1515+ grid[x, y] = int(c)
1616+1717+# Check what trees are visible.
1818+visibles = set()
1919+scenic_scores = {}
2020+2121+for tree in grid:
2222+ scores = []
2323+ for dx, dy in DIRS:
2424+ x, y = tree
2525+ score = 0
2626+ while (x, y) in grid:
2727+ nx = x + dx
2828+ ny = y + dy
2929+3030+ # Are we at the edge yet?
3131+ if (nx, ny) not in grid:
3232+ visibles.add(tree)
3333+ break
3434+ elif grid[nx, ny] >= grid[tree]:
3535+ score += 1
3636+ break
3737+3838+ x = nx
3939+ y = ny
4040+ score += 1
4141+4242+ scores.append(score)
4343+4444+ scenic_scores[tree] = mul(scores)
4545+4646+print("Part 1:", len(visibles))
4747+print("Part 2:", max(scenic_scores.values()))