[英]Generalize hourglass movement in 2D Array - DS in Python
While working through this HackerRank challenge to prepare for interviews, stumbled across a blocker.在通过这个 HackerRank 挑战为面试做准备时,偶然发现了一个障碍。
Basically want to create a function hourglassSum that should return an integer (the maximum hourglass sum in the array).基本上想创建一个 function hourglassSum,它应该返回一个 integer(数组中的最大沙漏总和)。 Given a 6 x 6 2D Array, arr:
给定一个 6 x 6 二维数组,arr:
1 1 1 0 0 0
0 1 0 0 0 0
1 1 1 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
There are 16 hourglasses in arr, and an hourglass sum is the sum of an hourglass' values. arr 中有 16 个沙漏,沙漏总和是沙漏值的总和。 In that case, the sum of an hourglass' is 7.
在这种情况下,沙漏的总和为 7。
This is the code I currently have (it's commented so it should be easy to understand the decisions being made too)这是我目前拥有的代码(它已被注释,因此也应该很容易理解所做的决定)
def hourglassSum(arr):
#print(f"arr: {arr}")
#print(f"arr[1]: {arr[1]}")
#print(f"arr[1][1]: {arr[1][1]}")
num_rows = len(arr)
num_cols = len(arr[0])
hg_total = 0
hg_current_sum = 0
hg_max_sum = 0
i = 0
j = 0
# There's no hourglass
if 0 <= num_rows <= 3 or 0 <= num_cols <= 3:
hg_total = 0
hg_max_sum = 0
# There's hourglass
else:
if num_rows > num_cols:
# hg_total = num_cols - 2 + ( num_rows - num_cols )
hg_total = num_rows - 2
#elif num_cols > num_rows:
else:
# hg_total = num_rows - 2 + ( num_cols - num_rows )
hg_total = num_cols - 2
# irrelevant and could be added to any of the others, transforming the elif into else
# else:
# hg_total = num_rows - 2
# only one hourglass
if hg_total == 1:
# calculate hg_current_sum
row_1 = arr[0][0:3]
row_2 = arr[1][1]
row_3 = arr[2][0:3]
#input
"""
1 1 1 0 0 0
0 1 0 0 0 0
1 1 1 0 0 0
0 0 2 4 4 0
0 0 0 2 0 0
0 0 1 2 4 0
"""
#print(f"row_1: {row_1}")
#print(f"row_2: {row_2}")
#print(f"row_3: {row_3}")
#output
"""
row_1: [1, 1, 1]
row_2: 1
row_3: [1, 1, 1]
"""
# Note that row_2 won't have sum() because it'll be always int and not a list of numbers
hg_current_sum = sum(row_1) + row_2 + sum(row_3)
hg_max_sum = hg_current_sum
return hg_max_sum
# Generalize
while i < num_rows:
row_1 = arr[i][0:3]
row_2 = arr[i+1][1]
row_3 = arr[i+2][0:3]
hg_current_sum = sum(row_1) + row_2 + sum(row_3)
# 9 is the highest value for a cell
# 7 is the amount of cells in each hourglass
# lowest_sum = -9 * 7
# Hightest_sum = 9 * 7
if hg_current_sum == 9*7:
hg_max_sum = hg_current_sum
break
elif hg_current_sum > hg_max_sum:
hg_max_sum = hg_current_sum
i = i + 2
while j < num_cols:
row_1 = arr[0][j:j+2]
row_2 = arr[1][j+1]
row_3 = arr[2][j:j+2]
hg_current_sum = sum(row_1) + row_2 + sum(row_3)
# 9 is the highest value for a cell
# 7 is the amount of cells in each hourglass
# lowest_sum = -9 * 7
# Hightest_sum = 9 * 7
if hg_current_sum == 9*7:
hg_max_sum = hg_current_sum
break
elif hg_current_sum > hg_max_sum:
hg_max_sum = hg_current_sum
j = j + 2
return hg_max_sum
If I execute this, it will give a如果我执行这个,它会给出一个
Error (stderr) Traceback (most recent call last): File
错误 (stderr) 回溯(最近调用最后一次):文件
"Solution.py", line 119, in
“Solution.py”,第 119 行,在
result = hourglassSum(arr) File "Solution.py", line 74, in hourglassSum
结果 = hourglassSum(arr) 文件“Solution.py”,第 74 行,在 hourglassSum 中
row_3 = arr[i+2][0:3] IndexError: list index out of range
row_3 = arr[i+2][0:3] IndexError: 列表索引超出范围
The problem I'm having is in the generalization of the behaviour, from the comment # Generalize
onwards.我遇到的问题是行为的泛化,从评论
# Generalize
开始。 That moment onwards, starts the scenario of more than one hourglasses.那一刻起,开始了不止一个沙漏的场景。
I can see how the movement of the hourglass should happen: top left -> top right (moving 1 cell to the right until the furthest right cell in the hourglass reaches the last existing column in the array) and repeat this process moving 1 cell down until the furthest down cell in the hourglass reaches the last row / bottom of the array.我可以看到沙漏的移动方式:左上角 -> 右上角(向右移动 1 个单元格,直到沙漏中最右边的单元格到达数组中最后一个现有列)并重复此过程,向下移动 1 个单元格直到沙漏中最下方的单元格到达数组的最后一行/底部。
Can see it could be done with a for loop (going from left -> right) inside of a for loop (going from top -> bottom).可以看到它可以通过 for 循环(从顶部 -> 底部)内部的 for 循环(从左 -> 右)来完成。 So, something like
所以,像
for i in range(num_rows)
# do stuff
for j in range(num_cells)
# do stuff
This would ofc make the part within loops nearly unnecessary;这通常会使循环内的部分几乎没有必要; the only reason I have them here is to visualize the movement of each cell to the right or to the bottom.
我把它们放在这里的唯一原因是可视化每个单元格向右或向底部的移动。
What then?然后怎样呢?
Moving to the right, I would update each part of the hourglass as a "sliding window," subtracting the former leftmost element and adding the new rightmost element.向右移动,我会将沙漏的每个部分更新为“滑动 window”,减去之前最左边的元素并添加新的最右边元素。 Start a new hourglass when moving the hourglass down a row.
将沙漏向下移动一行时开始一个新的沙漏。
Here's JavaScript code, easily convertable to Python:这是 JavaScript 代码,可轻松转换为 Python:
function f(m){ if (m.length < 3 || m[0].length < 3) return null; let row1, row2, row3; let best = -Infinity; for (let i=0; i<m.length-2; i++){ // Update the hourglass moving down row1 = m[i][0] + m[i][1] + m[i][2]; row2 = m[i+1][1]; row3 = m[i+2][0] + m[i+2][1] + m[i+2][2]; best = Math.max(best, row1 + row2 + row3); for (let j=1; j<m[0].length-2; j++){ // Update the hourglass moving to the right row1 += m[i][j+2] - m[i][j-1]; row2 = m[i+1][j+1]; row3 += m[i+2][j+2] - m[i+2][j-1]; best = Math.max(best, row1 + row2 + row3); } } return best; } var m = [ [1, 1, 1, 0, 0, 0], [0, 1, 0, 0, 0, 0], [1, 1, 1, 0, 0, 0], [0, 0, 2, 4, 4, 0], [0, 0, 0, 2, 0, 0], [0, 0, 1, 2, 4, 0] ]; console.log(f(m));
and here's the Python code:这是 Python 代码:
def hourglassSum(arr):
#print(f"arr: {arr}")
#print(f"arr[1]: {arr[1]}")
#print(f"arr[1][1]: {arr[1][1]}")
num_rows = len(arr)
num_cols = len(arr[0])
hg_max_sum = -float('Inf') #-inf
hg_current_sum = 0
i = 0
j = 1
# There's no hourglass
if 0 <= num_rows <= 3 or 0 <= num_cols <= 3:
hg_max_sum = 0
for i in range(0,num_rows - 2):
# Update the hourglass moving down
row1 = arr[i][0] + arr[i][1] + arr[i][2];
row2 = arr[i+1][1];
row3 = arr[i+2][0] + arr[i+2][1] + arr[i+2][2];
hg_current_sum = row1 + row2 + row3
#print(f"1_ hg_current_sum: {hg_current_sum}")
hg_max_sum = max(hg_max_sum, hg_current_sum);
#print(f"1_ hg_max_sum: {hg_max_sum}")
for j in range(1,num_cols - 2):
# Update the hourglass moving to the right
row1 += arr[i][j+2] - arr[i][j-1];
row2 = arr[i+1][j+1];
row3 += arr[i+2][j+2] - arr[i+2][j-1];
hg_current_sum = row1 + row2 + row3
#print(f"2_ hg_current_sum: {hg_current_sum}")
hg_max_sum = max(hg_max_sum, hg_current_sum);
#print(f"2_ hg_max_sum: {hg_max_sum}")
return hg_max_sum
basically the difference is that now基本上不同的是现在
This will pass all the current tests这将通过所有当前测试
public static int hourglassSum(List<List<int>> arr)
{
int[] sum = new int[16];
int hourglass = 0;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
sum[hourglass] =
arr[i][j] + arr[i][j + 1] + arr[i][j + 2]
+ arr[i + 1][j + 1]
+ arr[i + 2][j] + arr[i + 2][j + 1] + arr[i + 2][j + 2];
hourglass++;
}
}
return sum.Max();;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.