Пример для "классического" кубика-октаэдра. Определяем сумму и сумму квадратов на кубиках:
Вычисляем наибольшее возможное по модулю число на гранях, очевидно это
. Далее обе суммы представляем в виде двух сумм
,
(подразумеваем, что в каждом слагаемом сумма от четырёх граней); возможно, что тут оптимальнее будет представлять в виде суммы трёх или четырёх слагаемых, я поленился проверять. Это улучшение (оно существенно ускоряет счёт) я дописал после сообщения
Sender. Будет двойной цикл по
, можно наоборот по
, но прежде определим две очевидные функции:
Код:
S21[S22_] := S2 - S22;
S11[S12_] := S1 - S12;
Цикл
Код:
S12S22 = {}; Do[
If[S12^2/4 <= S22 && S11[S12]^2/4 <= S21[S22],
AppendTo[S12S22, {S12, S22}]], {S12, -4Floor[\sqrt{S_2}] 4Floor[\sqrt{S_2}]}, {S22, 0, S2}]
В нём пробегаем по всем возможным значениям
и
; поскольку в сумме
наибольшее возможное по модулю слагаемое равно
, а всего слагаемых четыре, то пределы по
от
до
(тут, конечно, можно ещё существенно сузить интервал, но тоже поленился). В цикле делается проверка удовлетворяют ли пары
,
неравенству для среднего арифметического и среднего квадратичного. На выходе имеем строку (одномерный массив)
, в котором все допустимые суммы разбиения восьмигранного кубика на два четырёхгранных. Ищем для каждого элемента
решение и одновременно решение для сопряжённой пары
, если решения одновременно существуют, то будем комбинировать решения, цикл проходит по всем найденным разбиениям:
Код:
str = {}; Do[(s2 = Solve[{Sum[l[i], {i, 1, 4}] == S12S22[[j, 1]], Sum[l[i]^2, {i, 1, 4}] == S12S22[[j, 2]], l[1] <= l[2] <= l[3] <= l[4]}, Table[l[i], {i, 1, 4}], Integers]; s1 = Solve[{Sum[l[i + 4], {i, 1, 4}] == S11[S12S22[[j, 1]]], Sum[l[i + 4]^2, {i, 1, 4}] == S21[S12S22[[j, 2]]], l[5] <= l[6] <= l[7] <= l[8]}, Table[l[i], {i, 5, 8}], Integers]; If[Length[s1] != 0 && Length[s2] != 0, Do[AppendTo[str, Sort[Union[s1[[k]], s2[[kk]]]]], {k, 1, Length[s1]}, {kk, 1, Length[s2]}]]; If[IntegerQ[j/10], Print[j]]), {j, 1, Length[S12S22]}] // Timing
Можно не пользоваться встроенной функцией Solve, она с опцией Integers всё равно ищет целочисленные решения обычным перебором, но для маленького числа переменных (в нашем случае их четыре) ускорение по-моему не будет существенным. В цикле есть место
Код:
If[Length[s1] != 0 && Length[s2] != 0, Do[AppendTo[str, Sort[Union[s1[[k]], s2[[kk]]]]], {k, 1, Length[s1]}, {kk, 1, Length[s2]}]]
То есть если одновременно нашлись решения, то мы составляем из найденных решений всевозможные комбинации, они являются решениями для восьмигранника. Наконец, формируем отсортированный массив найденных решений и выбрасываем повторяющиеся:
Код:
STR = {}; Do[ AppendTo[STR, Sort[{Last[str[[i, 1]]], Last[str[[i, 2]]], Last[str[[i, 3]]], Last[str[[i, 4]]], Last[str[[i, 5]]], Last[str[[i, 6]]], Last[str[[i, 7]]], Last[str[[i, 8]]]}]], {i, 1, Length[str]}]
Union[STR]
Length[Union[STR]]
Ссылка на nb файл:
https://dropmefiles.com/Z3OPdКстати, пока писал сообщение подумал, что надо попробовать каждый раз разбивать суммы на два слагаемых, то есть собрать всё вышеописанное в одну процедуру и вызывать её рекурсивно. Почти уверен, что тогда до додекаэдра доберёмся очень легко. Ведь идея
Sender ускоряет процесс в несколько раз.