I'm trying to simplify my solution to Project Euler's problem 11 (find the greatest product of 4-in-a-row numbers in a 20x20 grid).
My main gripe with my answer are the four try/except clauses in the definition of sub_lists_at_xy. I have one for each direction (east, south, southeast, and southwest) of 4-in-a-row lists that could possibly run off the board. Do you have any suggestions for simplifying or DRYing up 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][x-i] 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)
To follow the don't-repeat-yourself rule, you could 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 didn't get the directions wrong -- I usually make sign errors all over the place -- but you get the idea.
[Note: this isn't how I myself would do it, but it's how I would simplify your code.]
You could check the input, but you could also pad 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)
You can then filter your data
reduce(mul, [x for x in lst if x != "X"], 1)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With