How to dry directed logic with try / except mess

I am trying to simplify my solution Problem Project Euler 11 (find the largest product from the numbers 4 in a row in a 20x20 grid).

My main problem with my answer is the four try / except parameters in the sub_lists_at_xy definition. I have one for each direction (east, south, southeast and southwest) 4-line lists that could escape from the board. Do you have any suggestions for simplifying or draining this implementation?

from operator import mul with open("11.txt") as f: nums = [[int(num) for num in line.split(' ')] for line in f.read().split('\n')] def prod(lst): return reduce(mul, lst, 1) def sub_lists_at_xy(array, length, x, y): try: east=array[y][x:x+length] except IndexError: east=[0]*length try: south=[list[x] for list in array[y:y+length]] except IndexError: south=[0]*length try: southeast=[array[y+i][x+i] for i in range(length)] except IndexError: southeast=[0]*length try: southwest=[array[y+i][xi] for i in range(length)] except IndexError: southwest=[0]*length return east, south, southeast, southwest sub_lists=[] for x in range(len(nums[0])): for y in range(len(nums)): sub_lists += sub_lists_at_xy(nums, 4, x, y) best = max(prod(lst) for lst in sub_lists) print(best) 
+6
source share
2 answers

To follow the don't-repeat-yourself rule, you can pull out the direction logic:

 def sub_lists_at_xy(array, length, x, y): directions = [(1, 0), (0, 1), (1, 1), (-1, 1)] sublists = [] for dx, dy in directions: try: seq = [array[y+dy*i][x+dx*i] for i in range(length)] sublists.append(seq) except IndexError: pass return sublists 

You might want to check that I am not mistaken in the directions - I usually make mistakes with errors everywhere, but you get the idea.

[Note: this is not how I do it myself, but this is how I would simplify your code.]

+3
source

You can check the input, but you can also use your array

 with open("11.txt") as f: nums = [["X"] + [int(num) for num in line.split(' ')] + ["X"] for line in f.read().split('\n')] nums = ["X"]*(len(nums[0])+2) + nums + ["X"]*(len(nums[0])+2) 

Then you can filter your data

 reduce(mul, [x for x in lst if x != "X"], 1) 
+2
source

Source: https://habr.com/ru/post/921539/


All Articles