-
Notifications
You must be signed in to change notification settings - Fork 0
/
p11_largest_product_in_grid_with_window.py
80 lines (67 loc) · 2.78 KB
/
p11_largest_product_in_grid_with_window.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# Gets max product and its corresponding window/block
import math
import time
start_time = time.perf_counter()
# Let n = the amount of numbers in the input matrix
# Let k = the size of the window / number of products
# Runtime complexity:
# O(n)
# Memory consumption:
# 4 lists of size k are created every iteration; We iterate n times
# O(4kn) = O(n) (k is a constant) (not including input matrix)
def buildMatrixFromFile(file_name: str) -> list[list[int]]:
file = open(file_name)
matrix = []
for line in file:
row = line.rstrip().split(" ")
parsed_row = list(map(int, row))
matrix.append(parsed_row)
file.close()
return matrix
def getLargestWindow(*windows: list[int]): # *args
max_product = 1
max_window = [1]
for window in windows:
product = math.prod(window)
if product > max_product:
max_window = window
max_product = product
return max_product, max_window
def maxNProductInMatrix(matrix: list[list[int]], n: int) -> tuple[int, list[int]]:
def buildHorizontal(row: list[int], colIdx: int, n: int):
return row[colIdx : colIdx + n] # list slicing
def buildVertical(rowIdx: int, colIdx: int, n: int):
return [ matrix[rowIdx + i][colIdx] for i in range(n) ] # list comprehension
def buildDiagonalDown(rowIdx: int, colIdx: int, n: int):
return [ matrix[rowIdx + i][colIdx + i] for i in range(n) ]
def buildDiagonalUp(rowIdx: int, colIdx: int, n: int):
return [ matrix[rowIdx + n - 1 - i][colIdx + i] for i in range(n) ]
max_product = 1
max_window = []
for rowIdx, row in enumerate(matrix):
for colIdx, _ in enumerate(row):
horizontal = []
vertical = []
diagonalDown = []
diagonalUp = []
if rowIdx <= len(matrix) - n and colIdx <= len(row) - n:
horizontal = buildHorizontal(row, colIdx, n)
vertical = buildVertical(rowIdx, colIdx, n)
diagonalDown = buildDiagonalDown(rowIdx, colIdx, n)
diagonalUp = buildDiagonalUp(rowIdx, colIdx, n)
elif rowIdx <= len(matrix) - n:
vertical = buildVertical(rowIdx, colIdx, n)
elif colIdx <= len(row) - n:
horizontal = buildHorizontal(row, colIdx, n)
product, window = getLargestWindow(horizontal, vertical, diagonalDown, diagonalUp)
if product > max_product:
max_window = window
max_product = product
return max_product, max_window
matrix = buildMatrixFromFile("./11_input.txt")
product, window = maxNProductInMatrix(matrix, 4)
print(f"Product: {product}")
print(f"Window: {window}")
# Performance timer
end_time = time.perf_counter()
print(f"it took : {(end_time - start_time) * 1000:0.3f}ms")