Given a n*m matrix.
[[0,0,0,0]
[0,0,0,0]
[0,0,0,0]
[0,0,0,0]]
Then we need to fill in the matrix with smaller blocks such that the new blocks occupy empty space and don't overlap with existing blocks.
For example, after putting a block of 2*2, the matrix looks as below:
[[1,1,0,0]
[1,1,0,0]
[0,0,0,0]
[0,0,0,0]]
Return -1
if no space available in the bigger matrix.
My Code:
matrix_m = 4
matrix_n = 3
block_m = 2
block_n = 2
matrix = [[0]*matrix_n for _ in range(matrix_m)]
block = [[1]*block_n for _ in range(block_m)]
def solution(matrix, block):
from collections import deque
m = len(matrix)
n = len(matrix[0])
bm = len(block)
bn = len(block[0])
d = deque()
for r in range(bm):
for c in range(bn):
d.append(block[r][c])
for row in range(m):
for col in range(n):
if matrix[row][col] == 0:
if d:
matrix[row][col] = d.popleft()
else:
break
return matrix
solution(matrix, block)
Output:
[[1, 1, 1], [1, 0, 0], [0, 0, 0], [0, 0, 0]]
Expected Output:
[[1, 1, 0], [1, 1, 0], [0, 0, 0], [0, 0, 0]]
How to modify the def(solution)
to get the expected output?
Does the below logic looks correct to find the next available block?
for i,row in enumerate(block):
for j,val in enumerate(row):
while i<m and j<n:
if matrix[i][j] == 0:
if d:
matrix[i][j] = d.popleft()
else:
break
i = 1
j = 1
CodePudding user response:
this is an NP-Hard problem ... it is known as rectangle packing you can find some various algorithms pretty easily, but it is a computationally hard problem.. that said here is a modified version that correectly fills the matrix with just this one square
def solution(matrix, block):
# make a copy to not overwrite original
m2 = copy.deepcopy(matrix)
for i,row in enumerate(block):
for j,val in enumerate(row):
# fill some squares with the values from "block"
m2[i][j] = val
return m2 # return copy