Пане /KIT\, ну не тупо ж мініфікувати (до речі, ви дволітерні ідентифікатори використовуєте, коли ще не вичерпалися однолітерні). Принаймні, не до основних оптимізацій.
Наприклад, зараз я бачу, що parallelogram_matches завжди має хоча б пару однакових параметрів (а використовує вона їх симетрично). Отже, можна зробити
def parallelogram_matches(x,z):
return x*(x+1)*(z+1)+(x+1)*x*(z+1)+(x+1)*(x+1)*z
а це далі скорочується до
def parallelogram_matches(x,z):
return 2*x*(x+1)*(z+1)+(x+1)*(x+1)*z
можна ще спробувати
def parallelogram_matches(x,z):
return (x+1)*(2*x*(z+1)+(x+1)*z)
А якщо дужки в зовнішних розкрити, то матимемо
def parallelogram_matches(x,z):
return (x+1)*(3*x*z+2*x+z)
поки що виходить з 85 символів 63 проти ваших 57 - але ж це ще без жодної мініфікації, та й ще з десяток символів далі по коду вилетить, бо тепер замість parallelogram_matches(s+1,s+1,s) пишемо parallelogram_matches(s+1,s).
До речі, я якогось біса тут parallelogram замість parallelepiped написав. А насправді ж треба писати box, і тоді
def box_matches(x,z):
return (x+1)*(3*x*z+2*x+z)
53 символи без мініфікації - проти ваших 57.
Ще можна подумати, як ефективно отримувати найбільше число, 2-ий чи 3-ій степіть котрого не перевищує задане. Оскільки 1/3 трохи менше за третину, int(125**(1/3)) дає 4; через це мені довелося дописати оте
side = int(n**(1/3))
if (side+1)**3==n:
side+=1
Але, гадаю, це можна вирішити якось простіше (і коротше); скажімо,
side = int((n+.5)**(1/3))
і т.д.