Created
November 29, 2010 19:50
Revisions
-
creationix renamed this gist
Nov 29, 2010 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
creationix revised this gist
Nov 29, 2010 . 2 changed files with 1 addition and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,5 +1,3 @@ function rectify(grid) { var rects = {}; function findRect1(x, y) { This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1 @@ <img src="http://creationix.com/rectify.png"> -
creationix revised this gist
Nov 29, 2010 . 2 changed files with 44 additions and 29 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,44 @@ # Rectify Takes a grid and returns an optimal set of rectangles that fills that grid For example, the following grid: [[1,1,0,1,1], [1,1,1,1,1], [0,1,1,1,0]] Should result in three rectangles (order doesn't matter) [{x:0,y:0,w:2,h:2}, {x:3,y:0,w:2,h:2}, {x:1,y:1,w:3,h:2}] Note that the rectangles need to overlap and not simply touch since they will be used to draw a shape with rounded and slightly inset borders. [[1,1,0], [1,1,1], [0,0,1]] Even though the following technically fills all the space: [{x:0,y:0,w:2,h:2}, {x:2,y:1,w:1,h:2}] It will appear as two distinct rectangles because they don't overlap. The following is correct: [{x:0,y:0,w:2,h:2}, {x:2,y:1,w:1,h:2}, {x:0,y:2,w:3,h:1}] ## The Challenge The following implementation works, but the result it not optimal, it often results in too many rectangles. Also there are some fairly expensive parts to the algorithm and it's a bit longer than I would like. Clone this gist and make a better implementation and link to your submission as a comment here when done. This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,33 +1,4 @@ function rectify(grid) { var rects = {}; -
creationix created this gist
Nov 29, 2010 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,127 @@ // Takes a grid and returns an optimal set of rectangles that fills that grid // For example: // [[1,1,0,1,1], // [1,1,1,1,1], // [0,1,1,1,0]] // Should result in three rectangles (order doesn't matter) // [{x:0,y:0,w:2,h:2}, // {x:3,y:0,w:2,h:2}, // {x:1,y:1,w:3,h:2}] // Note that the rectangles need to overlap and not simply touch since they // will be used to draw a shape with rounded and slightly inset borders. // [[1,1,0], // [1,1,1], // [0,0,1]] // Even though the following technically fills all 1's: // [{x:0,y:0,w:2,h:2}, // {x:2,y:1,w:1,h:2}] // It will appear as two distinct rectangles because they don't overlap // the following is correct // [{x:0,y:0,w:2,h:2}, // {x:2,y:1,w:1,h:2}, // {x:0,y:2,w:3,h:1}] // THE CHALLENGE: // The following implementation works, but the result it not optimal, it // often results in too many rectangles. Also there are some fairly expensive // parts to the algorithm and it's a bit longer than I would like. // // Clone this gist and make a better implementation and link to your submission // as a comment here when done. function rectify(grid) { var rects = {}; function findRect1(x, y) { var sx = x, sy = y, ex = x, ey = y; while (grid[sy - 1] && grid[sy - 1][x]) { sy--; } while (grid[ey + 1] && grid[ey + 1][x]) { ey++; } var good = true; var ty; while (good) { for (ty = sy; ty < ey + 1; ty++) { if (!grid[ty][sx - 1]) { good = false; break; } } if (good) { sx--; } } good = true; while (good) { for (ty = sy; ty < ey + 1; ty++) { if (!grid[ty][ex + 1]) { good = false; break; } } if (good) { ex++; } } return { x: sx, y: sy, w: ex - sx + 1, h: ey - sy + 1 }; } function findRect2(x, y) { var sx = x, sy = y, ex = x, ey = y; while (grid[y][sx - 1]) { sx--; } while (grid[y][ex + 1]) { ex++; } var good = true; var tx; while (good) { for (tx = sx; tx < ex + 1; tx++) { if (!(grid[sy - 1] && grid[sy - 1][tx])) { good = false; break; } } if (good) { sy--; } } good = true; while (good) { for (tx = sx; tx < ex + 1; tx++) { if (!(grid[ey + 1] && grid[ey + 1][tx])) { good = false; break; } } if (good) { ey++; } } return { x: sx, y: sy, w: ex - sx + 1, h: ey - sy + 1 }; } for (var y = 0, l1 = grid.length; y < l1; y++) { for (var x = 0, l2 = grid[y].length; x < l2; x++) { if (grid[y][x]) { rects[JSON.stringify(findRect1(x, y))] = true; rects[JSON.stringify(findRect2(x, y))] = true; } } } // TODO: Remove redundant rectangles return Object.keys(rects).map(function (json) { return JSON.parse(json); }); }