I have N scalable square tiles (buttons) that need to be placed inside of fixed sized rectangular surface (toolbox). I would like to present the buttons all at the same size.
How could I solve for the optimal size of the tiles that would provide the largest area of the rectangular surface being covered by tiles.
Let
WandHbe the width and height of the rectangle.Let
sbe the length of the side of a square.Then the number of squares
n(s)that you can fit into the rectangle isfloor(W/s)*floor(H/s). You want to find the maximum value ofsfor whichn(s) >= NIf you plot the number of squares against
syou will get a piecewise constant function. The discontinuities are at the valuesW/iandH/j, whereiandjrun through the positive integers.You want to find the smallest
ifor whichn(W/i) >= N, and similarly the smallestjfor whichn(H/j) >= N. Call these smallest valuesi_minandj_min. Then the largest ofW/i_minandH/j_minis thesthat you want.I.e.
s_max = max(W/i_min,H/j_min)To find
i_minandj_min, just do a brute force search: for each, start from 1, test, and increment.In the event that N is very large, it may be distasteful to search the
i‘s andj‘s starting from 1 (although it is hard to imagine that there will be any noticeable difference in performance). In this case, we can estimate the starting values as follows. First, a ballpark estimate of the area of a tile isW*H/N, corresponding to a side ofsqrt(W*H/N). IfW/i <= sqrt(W*H/N), theni >= ceil(W*sqrt(N/(W*H))), similarlyj >= ceil(H*sqrt(N/(W*H)))So, rather than start the loops at
i=1andj=1, we can start them ati = ceil(sqrt(N*W/H))andj = ceil(sqrt(N*H/W))). And OP suggests thatroundworks better thanceil— at worst an extra iteration.Here’s the algorithm spelled out in C++:
The above is written for clarity. The code can be tightened up considerably as follows: