I want to build a function that, given an area size (target
), returns a list of three lengths. The last item of the list (my_list[-1]
) corresponds to the square plate.
The first two lengths in the list correspond to an orthogonal plate whose length is approximately 1.5 times larger than the one of the square plate and whose width is 1.5 times smaller. I want the lengths to be whole numbers.
The function I wrote for the task is given below, but I am sure there is a much better/faster solution. Keep in mind that when it comes to rounding floats, the bigger size for the length must be chosen since it is more conservative, but the main consideration is to not overshoot the target more than I have to.
import math
def get_plates(target):
square = math.ceil(target ** 0.5)
ortho1 = [math.ceil(target ** 0.5 * 1.5), math.floor(target ** 0.5 * 1.5)]
ortho2 = [math.ceil(target ** 0.5 / 1.5), math.floor(target ** 0.5 / 1.5)]
temp = list(zip([ortho1[0] for _ in ortho2], ortho2))
temp.extend(list(zip([ortho1[1] for _ in ortho2], ortho2)))
temp = [x for x in temp if x[0]*x[1] >= target]
temp.sort(key=lambda x: abs(x[0] * x[1] - target))
return [*temp[0], square]
For example, for a target = 700
the get_plates(700)
correctly returns [39, 18, 27]
and not [40, 18, 27]
since 39x18 = 702 whereas 40x18 = 720 and 40x17 = 680
How can the above be made more efficient?