Skip to content

Instantly share code, notes, and snippets.

@amadanmath
Created August 17, 2017 02:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amadanmath/7172683afef2367f4444aa4250e01d16 to your computer and use it in GitHub Desktop.
Save amadanmath/7172683afef2367f4444aa4250e01d16 to your computer and use it in GitHub Desktop.
Biggest box size, using dynamic programming
#!/usr/bin/env ruby
input = [
[1,0,0,0,1,0,0,0,0,1,0,0,0,0,0],
[1,0,0,0,1,0,0,0,0,0,0,0,0,0,0],
[1,0,0,0,1,0,0,0,0,1,0,0,0,0,0],
[1,0,1,0,1,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,1,1,0,1,0,0,0,0,0],
[0,0,0,0,0,0,0,1,0,0,0,0,1,0,0],
[0,0,0,0,0,0,1,0,0,0,0,1,0,0,0],
[0,0,0,0,0,0,1,0,0,1,0,0,1,0,0],
[0,0,0,0,0,0,0,0,1,0,0,0,0,0,0],
[0,0,0,0,0,0,1,0,0,0,0,0,0,0,0]
]
def biggest_box_size(input)
max_area = 0
# make an empty array of arrays
boxes = input.map { |row| [] }
input.each_with_index do |row, i|
row.each_with_index do |cell, j|
left = j > 0 ? boxes[i][j - 1] : nil
above = i > 0 ? boxes[i - 1][j] : nil
boxes[i][j] =
# [rows, columns]
case
when cell == 1
# if the corner is filled, it doesn't complete a box
[0, 0]
when i.zero? && j.zero?
# otherwise, if top-left corner, it has size 1x1
[1, 1]
when i.zero?
# otherwise, if top row, it grows the left box by one column
[1, left[1] + 1]
when j.zero?
# otherwise, if left column, it grows the above box by one row
[above[0] + 1, 1]
else
# the general case
# left box + column
if left[0].zero?
left_with_column_area = 0
else
left_with_column = [[left[0], above[0] + 1].min, left[1] + 1]
left_with_column_area = left_with_column[0] * left_with_column[1]
end
# above box + row
if above[1].zero?
above_with_row_area = 0
else
above_with_row = [above[0] + 1, [above[1], left[1] + 1].min]
above_with_row_area = above_with_row[0] * above_with_row[1]
end
# if both above and left is blocked
if left_with_column_area.zero? && above_with_row_area.zero?
# make a new box
[1, 1]
else
# otherwise, take the larger one
left_with_column_area > above_with_row_area ? left_with_column : above_with_row
end
end
area = boxes[i][j][0] * boxes[i][j][1]
max_area = area if area > max_area
end
end
max_area
end
if __FILE__ == $0
puts biggest_box_size(input)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment