Guest User

Untitled

a guest
Dec 14th, 2018
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.65 KB | None | 0 0
  1. from functools import reduce
  2.  
  3. # Generates all valid rectangles that have a lower left hand corner in i and j
  4. def validRectanglesFrom(grid, i, j):
  5. result = []
  6. w = 1
  7. while i + w <= len(grid) and grid[i + w - 1][j] == 1:
  8. h = 1
  9. row_is_valid = True
  10. while j + h <= len(grid[i + w - 1]) and row_is_valid:
  11. for k in range(i, i + w):
  12. if grid[k][j + h - 1] == 0:
  13. row_is_valid = False
  14. break
  15. if row_is_valid:
  16. result.append((i, j, w, h))
  17. h = h + 1
  18. w = w + 1
  19. return result
  20.  
  21. def left_edge_is_internal(grid, i, j):
  22. return i > 0 and grid[i - 1][j] == 1 and grid[i][j] == 1
  23.  
  24. def right_edge_is_internal(grid, i, j):
  25. return i < len(grid) - 1 and grid[i][j] == 1 and grid[i + 1][j] == 1
  26.  
  27. def bottom_edge_is_internal(grid, i, j):
  28. return j > 0 and grid[i][j - 1] == 1 and grid[i][j] == 1
  29.  
  30. def top_edge_is_internal(grid, i, j):
  31. return j < len(grid[i]) - 1 and grid[i][j] == 1 and grid[i][j + 1] == 1
  32.  
  33. def bottom_boundary_penalty(grid, rect):
  34. return len(
  35. list(
  36. filter(
  37. lambda isInt: isInt,
  38. map(
  39. lambda i: bottom_edge_is_internal(grid, i, rect[1]),
  40. range(rect[0], rect[0] + rect[2])
  41. )
  42. )
  43. )
  44. )
  45.  
  46. def top_boundary_penalty(grid, rect):
  47. return len(
  48. list(
  49. filter(
  50. lambda isInt: isInt,
  51. map(
  52. lambda i: top_edge_is_internal(grid, i, rect[1] + rect[3] - 1),
  53. range(rect[0], rect[0] + rect[2])
  54. )
  55. )
  56. )
  57. )
  58.  
  59. def left_boundary_penalty(grid, rect):
  60. return len(
  61. list(
  62. filter(
  63. lambda isInt: isInt,
  64. map(
  65. lambda j: left_edge_is_internal(grid, rect[0], j),
  66. range(rect[1], rect[1] + rect[3])
  67. )
  68. )
  69. )
  70. )
  71.  
  72. def right_boundary_penalty(grid, rect):
  73. return len(
  74. list(
  75. filter(
  76. lambda isInt: isInt,
  77. map(
  78. lambda j: right_edge_is_internal(grid, rect[0] + rect[2] - 1, j),
  79. range(rect[1], rect[1] + rect[3])
  80. )
  81. )
  82. )
  83. )
  84.  
  85. def boundary_penalty(grid, rect):
  86. return (
  87. bottom_boundary_penalty(grid, rect) +
  88. top_boundary_penalty(grid, rect) +
  89. left_boundary_penalty(grid, rect) +
  90. right_boundary_penalty(grid, rect)
  91. )
  92.  
  93. def internal_grid_edges(rect):
  94. return ((rect[2] - 1) * rect[3]) + (rect[2] * (rect[3] - 1))
  95.  
  96. def quality(grid, rect):
  97. return internal_grid_edges(rect) - boundary_penalty(grid, rect)
  98.  
  99. # This destroys your grid, so if you don't want that, clone it first
  100. def get_rectangles(grid):
  101. result = []
  102. grid_locations = [(i, j) for i in range(0, len(grid)) for j in range(0, len(grid[i]))]
  103. unfilled = {cell for cell in grid_locations if grid[cell[0]][cell[1]] == 1}
  104. while len(unfilled) > 0:
  105. rects = [rect for cell in unfilled for rect in validRectanglesFrom(grid, cell[0], cell[1])]
  106. qualityScores = list(map(lambda rect: quality(grid, rect), rects))
  107. bestRectIdx = reduce(lambda i, j: i if qualityScores[i] > qualityScores[j] else j, range(len(qualityScores)))
  108. bestRect = rects[bestRectIdx]
  109. result.append(bestRect)
  110. for i in range(bestRect[0], bestRect[0] + bestRect[2]):
  111. for j in range(bestRect[1], bestRect[1] + bestRect[3]):
  112. unfilled.remove((i,j))
  113. return result
  114.  
  115. grid = [[1, 1, 1], [0, 1, 0], [0, 1, 1], [0, 1, 0]]
  116. get_rectangles(grid)
Add Comment
Please, Sign In to add comment