(I suppose, perhaps by mistake, that your rectangles are infinitely divisible rather than composed of discrete pixels.)
You can always get exactly the right proportions for a small fee in empty rectangles by allowing m = ceil (sqrt (n)) and using m parts on each side.
Otherwise, you are looking for p, q close to sqrt (n), such that pq> = n and p, q are close to each other. The best choice p, q, of course, will depend on how you are willing to trade from inaccuracies. It doesn't seem likely that you will ever want to take p, q very far from sqrt (n), because it will give you a big error in the form. So I think you want something like this:
p = ceiling(sqrt(n)) best_merit_yet = merit_function(p,p,0) best_configuration_yet = (p,p) for p from floor(sqrt(n)) downward: # we need pq >= n and q as near to p as possible, which means (since p is too small) as small as possible q = ceiling(n/p) if max(merit_function(n/p,n/q,0), merit_function(n/q,n/p,0)) < best_merit_yet: break n_wasted = p*qn merit1 = merit_function(n/p,n/q,n_wasted) merit2 = merit_function(n/q,n/p,n_wasted) if max(merit1,merit2) > best_merit_yet: if merit1 > merit2: best_configuration_yet = (p,q) best_merit_yet = merit1 else: best_configuration_yet = (q,p) best_merit_yet = merit2
and hopefully the fact that the very wrong shapes are very bad will mean that you never have to take many iterations of the loop.
Here merit_function
should embody your preferences regarding trade in waste forms.