EDITED TO UPDATE MY CODE AND GIVE FULL RESPONSE TO @MOHAMMED
Picture, if you will, a cube. Each face of that cube has a group of 4 numbers. Each number on the cube only occurs once.
So far, I have managed, with some help from here, to write a program that filters those 24 numbers into a list where every face of 4 numbers totals 50, no pair on a face total 25, but every number and it's direct opposite (physically) total 25.
The problem I now have is the corners. I have a rule I wish to apply to them. The 3 numbers that met at each corner must all total 37 or 38. There are some other rules too, but for now let's just stick with that.
Now, like a die, opposite numbers all total to the same. This means, that for all intents, each group I have had an opposite, and as such, it can never be adjacent to it.
So my program has spat its first group of 6 faces that match my criteria. How do I now work out the corners?
I have realised that I only NEED to work with 3 of the 6 faces, as with each number being paired with an opposite to total 25, once one corner matches the rules, it's opposite should do as well.
I've simplified my code to just this issue.
group1 = list(['A','B','E','F'])
group2 = list(['A','D','E','G'])
group3 = list(['A','B','C','D'])
group4 = list(['E','F','G','H'])
group5 = list(['B','C','F','H'])
group6 = list(['C','D','G','H'])
for a in group1:
for b in group2:
for c in group3:
for corner1 in itertools.combinations((a,b,c),3):
if (a == b == c):
print (corner1)
Gives
('A','A','A')
Assuming there was no match, then there are two other possible group combinations after 1,2,3; and those are 1,3,5 and 1,4,5.
Using 1 as a constant by which all others are paired to make it a bit simpler, I think.
I have 2 issues, firstly, assuming our first match only appears in the last combination of groups, What would be the best way to write the code?
for a in group1:
for b in group2:
for c in group3:
for d in group4:
for e in group5:
for f in group6:
for corner1 in itertools.combinations((a,b,c),3):
else:
for corner1 in itertools.combinations((a,b,d),3):
else:
for corner1 in itertools.combinations((a,d,e),3):
Or:
for a in group1:
for b in group2:
for c in group3:
for corner1 in itertools.combinations((a,b,c),3):
else for a in group1:
for b in group2:
for c in group4:
for corner1 in itertools.combinations((a,b,d),3):
else for a in group1:
for b in group2:
for c in group3:
for corner1 in itertools.combinations((a,d,e),3):
And even if either of those bits of code are workable (I have my doubts on both as I'm a novice), I then need to both remove those numbers from further matches with the same group AND preserve the order of the groups.
For example, if the combination 1,2,4 is chosen by the first bit of the rule, how do I make certain that subsequent query's only work if that is true (oues that make sense?)
This is my complete code so far.... EDITED
n = 0
cnr1 = 0
cnr2 = 0
cnr3 = 0
cnr4 = 0
faces_all = list(range(1,25))
for x in itertools.combinations((faces_all[1:24]),3):
if faces_all[0] + sum(x) == 50:
side1 = (faces_all[0], x[0], x[1], x[2])
for pair in itertools.combinations(side1, 2):
if sum(pair) == 25:
break
else:
side6 = (25-side1[0], 25-side1[1], 25-side1[2], 25-side1[3])
faces_remaining = list(set(faces_all) - set(side1) - set(side6))
for y in itertools.combinations(faces_remaining,4):
if sum(y) == 50:
side2 = y
for pair in itertools.combinations(side2,2):
if sum(pair) == 25:
break
else:
side5 = (25-side2[0], 25-side2[1], 25-side2[2], 25-side2[3])
faces_last = list(set(faces_remaining) - set(side2) - set(side5))
for z in itertools.combinations(faces_last,4):
if sum(z) == 50:
side3 = z
for pair in itertools.combinations(side3,2):
if sum(pair) == 25:
break
else:
side4 = (25-side3[0], 25-side3[1], 25-side3[2], 25-side3[3])
for a in side2:
for b in side3:
for c in side4:
for d in side5:
for top in itertools.permutations(side1,4):
for corner1 in itertools.combinations((top[0],a,b),3):
if (sum(corner1) == 37 or sum(corner1) == 38):
corner8 = (25-top[0],25-a,25-b)
cnr1 += 1
print ("1&8",cnr1,"2&7",cnr2,"3&6",cnr3)
for corner2 in itertools.combinations((top[1],b,d),3):
#if (b not in corner1 and sum(corner1) + sum(corner2) == 75):
if sum(corner1) + sum(corner2) == 75:
corner7 = (25-top[1],25-b,25-d)
cnr2 += 1
print ("1&8",cnr1,"2&7",cnr2,"3&6",cnr3)
for corner3 in itertools.combinations((top[2],d,c),3):
#if (d not in corner1 and sum(corner3) == sum(corner1)):
if sum(corner3) == sum(corner1):
corner6 = (25-top[2],25-d,25-c)
cnr3 += 1
print ("1&8",cnr1,"2&7",cnr2,"3&6",cnr3)
for corner4 in itertools.combinations((top[2],c,a),3):
#if (c not in corner3 and a not in corner1 and sum(corner4) + sum(corner1) == 75):
if sum(corner4) + sum(corner1) == 75:
corner5 = (25-top[2],25-c,25-a)
print ("1&8",cnr1,"2&7",cnr2,"3&6",cnr3)
print (n)
print ("sides:", side1, side2, side3, side4, side5, side6)
print ("corners:", corner1, corner2, corner3, corner4, corner5, corner6)
The output (from start to where the code stops without error) is:
1&8 1 2&7 0 3&6 0
...
1&8 8109504 2&7 213792 3&6 5558
So 8 million hits for corners 1&8, only 200,000 for 1&8 AND 2&7, and only 5,000 for 1&8, 2&7, AND 3&6 - but nothing that includes 4&5).
This suggests that either what I am trying is not possible to achieve (which is possible), or there is something wrong with my code.
Attempt at diagrams to make it clearer:
A____________B
|\A B:\
|A\ :B\
| \ : \
| \D______:__C\C
| D|D : C|
E|E | F:F |
\```|````````. |
\ | . |
\H| .|
\|H_________G|G
H G
+-----+
| E F |
| A B |
+-----+-----+-----+-----+
| E A | A B | B F | F E |
| H G | D C | C G | G H |
+-----+-----+-----+-----+
| D c |
| H G |
+-----+
+----------------------+
|Ee fF|
| +--+----------+--+ |
| |37|e 50 f|38| |
| +--+--+ +--+--+ |`
| |E |38|a b|37| F| |
| | +--+----+--+ | |
| | Aa|A B|bB | |
| | 50 | 50 | 50 | |
| | Dd|D C|cC | |
| | +--+----+--+ | |
| |H |37|d c|38| G| |
| +--+--+ 50 +--+--+ |
| |38|h g|37| |
| +--+----------+--+ |
|Hh gG|
+----------------------+
===========================================================================
RESPONSE to @Mohammed's code
from itertools import combinations
# Filter functions
# ------------
## All sides add to 50
def check_sides(lst):
sides = [lst[0] + lst[1] + lst[2] + lst[3],
lst[4] + lst[5] + lst[12] + lst[13],
lst[6] + lst[7] + lst[14] + lst[15],
lst[8] + lst[9] + lst[16] + lst[17],
lst[10] + lst[11] + lst[18] + lst[19],
lst[20] + lst[21] + lst[22] + lst[23]]
return all(side == 50 for side in sides)
# All corners are 37 or 38
def check_corners(lst):
print(".")
corners = [lst[5] + lst[6] + lst[2],
lst[3] + lst[7] + lst[8],
lst[13] + lst[14] + lst[20],
lst[21] + lst[15] + lst[16],
lst[12] + lst[22] + lst[19],
lst[23] + lst[17] + lst[6],
lst[1] + lst[9] + lst[10],
lst[0] + lst[4] + lst[11]]
return all(36 < corner < 39 for corner in corners)
# All opposites add to 25
def check_opposites(lst):
print(lst)
opposites = [lst[0] + lst[22],
lst[2] + lst[20],
lst[1] + lst[23],
lst[3] + lst[21],
lst[5] + lst[8],
lst[4] + lst[9],
lst[12] + lst[17],
lst[13] + lst[16],
lst[7] + lst[10],
lst[6] + lst[11],
lst[15] + lst[18],
lst[14] + lst[19]]
return all(pair == 25 for pair in opposites)
# No pairs on a side add to 25
def check_pairs(lst):
pairs = [lst[0] + lst[1], lst[2] + lst[3],
lst[0] + lst[2], lst[1] + lst[3],
lst[0] + lst[3], lst[1] + lst[2],
lst[4] + lst[5], lst[12] + lst[13],
lst[4] + lst[12], lst[5] + lst[13],
lst[4] + lst[13], lst[5] + lst[12],
lst[6] + lst[7], lst[14] + lst[15],
lst[6] + lst[14], lst[7] + lst[15],
lst[6] + lst[15], lst[7] + lst[14],
lst[8] + lst[9], lst[16] + lst[17],
lst[8] + lst[16], lst[9] + lst[17],
lst[8] + lst[17], lst[9] + lst[16],
lst[10] + lst[11], lst[18] + lst[19],
lst[10] + lst[18], lst[11] + lst[19],
lst[10] + lst[19], lst[11] + lst[18],
lst[20] + lst[21], lst[22] + lst[23],
lst[20] + lst[22], lst[21] + lst[23],
lst[20] + lst[23], lst[21] + lst[22]]
return all(pair != 25 for pair in pairs)
# Everything else
# ---------------
def nFilter(filters, iterable):
for f in filters:
iterable = filter(f, iterable)
return iterable
candidates = combinations(range(1,50), 24)
#cubes = nFilter([check_sides, check_corners, check_opposites, check_pairs], candidates)
cubes = nFilter([check_sides],candidates)
for cube in cubes:
print(cube)
I've added in the missing "pairs" on each face (for 4 numbers there are 6 possible combinations of pairs (AB, AC, AD, BC, BD, CD).
I rearranged the order of checks to do the ones with the least arguments first.
But I'm not understanding the output, it seems that it is just printing all combinations of 24 numbers from 1 to n without applying the filters.
Changing combinations(range(1,50)
to combinations(range(1,26)
yields the following output, and changing it to combinations(range(1,25)
(which would then only utilise the numbers I want to use (1-24) only yields the first line of the output below.
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24)
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 25)
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25)
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 23, 24, 25)
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 23, 24, 25)
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24, 25)
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25)
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25)
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25)
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25)
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)
(1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)
(1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12,13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)
(1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12,13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)
(1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12,13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)
(1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12,13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)
(1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12,13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)
(1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12,13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)
(1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12,13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)
(1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)
(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)
===========================================================================
Adding more code:
Playing around I have the following 2 programs full of ugly if statements, but hopefully they are working.
So I have
face_combinations = 0
faces_all = list(range(1,25))
for side in combinations((faces_all[1:24]),3):
if faces_all[0] + sum(side) == 50:
if faces_all[0] + side[0] != 25:
if faces_all[0] + side[1] != 25:
if faces_all[0] + side[2] != 25:
if side[0] + side[1] != 25:
if side[0] + side[2] != 25:
if side[1] + side[2] != 25:
side1 = (faces_all[0], side[0], side[1], side[2])
side6 = (25-side1[0], 25-side1[1], 25-side1[2], 25-side1[3])
faces_remaining = list(set(faces_all) - set(side1) - set(side6))
for side in combinations(faces_remaining[1:16],4):
if faces_remaining[0] + sum(side) == 50:
if faces_remaining[0] + side[0] != 25:
if faces_remaining[0] + side[1] != 25:
if faces_remaining[0] + side[2] != 25:
if side[0] + side[1] != 25:
if side[0] + side[2] != 25:
if side[1] + side[2] != 25:
side2 = (faces_remaining[0], side[0], side[1], side[2])
side5 = (25-side2[0], 25-side2[1], 25-side2[2], 25-side2[3])
faces_last = list(set(faces_remaining) - set(side2) - set(side5))
for side in combinations(faces_last[1:8],4):
if faces_last[0] + sum(side) == 50:
if faces_last[0] + side[0] != 25:
if faces_last[0] + side[1] != 25:
if faces_last[0] + side[2] != 25:
if side[0] + side[1] != 25:
if side[0] + side[2] != 25:
if side[1] + side[2] != 25:
side3 = (faces_last[0], side[0], side[1], side[2])
side4 = (25-side2[0], 25-side2[1], 25-side2[2], 25-side2[3])
face_combinations += 1
print (face_combinations, side1, side2, side3, side4, side5, side6)
which yields:
2 (1, 4, 22, 23) (5, 6, 9, 12) (7, 8, 10, 11) (20, 19, 16, 13) (20, 19, 16, 13) (24, 21, 3, 2)
3 (1, 4, 22, 23) (5, 6, 9, 13) (7, 8, 10, 11) (20, 19, 16, 12) (20, 19, 16, 12) (24, 21, 3, 2)
4 (1, 4, 22, 23) (5, 6, 9, 14) (7, 8, 10, 12) (20, 19, 16, 11) (20, 19, 16, 11) (24, 21, 3, 2)
5 (1, 4, 22, 23) (5, 6, 11, 12) (7, 8, 9, 10) (20, 19, 14, 13) (20, 19, 14, 13) (24, 21, 3, 2)
6 (1, 4, 22, 23) (5, 6, 11, 13) (7, 8, 9, 10) (20, 19, 14, 12) (20, 19, 14, 12) (24, 21, 3, 2)
7 (1, 4, 22, 23) (5, 7, 8, 11) (6, 9, 10, 12) (20, 18, 17, 14) (20, 18, 17, 14) (24, 21, 3, 2)
8 (1, 4, 22, 23) (5, 7, 8, 12) (6, 9, 10, 11) (20, 18, 17, 13) (20, 18, 17, 13) (24, 21, 3, 2)
9 (1, 4, 22, 23) (5, 7, 8, 13) (6, 9, 10, 11) (20, 18, 17, 12) (20, 18, 17, 12) (24, 21, 3, 2)
10 (1, 4, 22, 23) (5, 7, 8, 14) (6, 9, 10, 12) (20, 18, 17, 11) (20, 18, 17, 11) (24, 21, 3, 2)
...
691 (1, 15, 16, 18) (2, 3, 5, 19) (4, 8, 11, 13) (23, 22, 20, 6) (23, 22, 20, 6) (24, 10, 9, 7)
692 (1, 15, 16, 18) (2, 4, 8, 13) (3, 5, 6, 14) (23, 21, 17, 12) (23, 21, 17, 12) (24, 10, 9, 7)
693 (1, 15, 16, 18) (2, 4, 11, 12) (3, 5, 6, 17) (23, 21, 14, 13) (23, 21, 14, 13) (24, 10, 9, 7)
694 (1, 15, 16, 18) (2, 4, 11, 13) (3, 5, 6, 17) (23, 21, 14, 12) (23, 21, 14, 12) (24, 10, 9, 7)
695 (1, 15, 16, 18) (2, 4, 13, 14) (3, 5, 6, 17) (23, 21, 12, 11) (23, 21, 12, 11) (24, 10, 9, 7)
696 (1, 15, 16, 18) (2, 5, 6, 14) (3, 4, 8, 13) (23, 20, 19, 11) (23, 20, 19, 11) (24, 10, 9, 7)
697 (1, 15, 16, 18) (2, 6, 11, 12) (3, 4, 5, 17) (23, 19, 14, 13) (23, 19, 14, 13) (24, 10, 9, 7)
And this:
numbers_all = list(range(1,25))
corner_combinations = 0
for corner in combinations((numbers_all[1:24]), 2):
if 36 < numbers_all[0] + sum(corner) < 39:
corner1 = (numbers_all[0], corner[0], corner[1])
if corner1[0] + corner1[1] != 25:
if corner1[0] + corner1[2] != 25:
if corner1[1] + corner1[2] != 25:
corner8 = (25 - corner1[0], 25 - corner1[1], 25 - corner1[2])
numbers_remaining = list(set(numbers_all) - set(corner1) - set(corner8))
for corner in combinations((numbers_remaining[1:18]), 2):
if 36 < numbers_remaining[0] + sum(corner) < 39:
corner2 = (numbers_remaining[0], corner[0], corner[1])
if sum(corner1) + sum(corner2) ==75:
if corner2[0] + corner2[1] != 25:
if corner2[0] + corner2[2] != 25:
if corner2[1] + corner2[2] != 25:
corner7 = (25 - corner2[0], 25 - corner2[1], 25 - corner2[2])
numbers_remaining2 = list(set(numbers_remaining) - set(corner2) - set(corner7))
for corner in combinations((numbers_remaining2[1:12]), 2):
if 36 < numbers_remaining2[0] + sum(corner) < 39:
corner3 = (numbers_remaining2[0], corner[0], corner[1])
if sum(corner3) == sum(corner1):
if corner3[0] + corner3[1] != 25:
if corner3[0] + corner3[2] != 25:
if corner3[1] + corner3[2] != 25:
corner6 = (25 - corner3[0], 25 - corner3[1], 25 - corner3[2])
numbers_remaining3 = list(set(numbers_remaining2) - set(corner3) - set(corner6))
for corner in combinations((numbers_remaining3[1:6]), 2):
if 36 < numbers_remaining3[0] + sum(corner) < 39:
corner4 = (numbers_remaining3[0], corner[0], corner[1])
if sum(corner1) + sum(corner4) ==75:
if corner4[0] + corner4[1] != 25:
if corner4[0] + corner4[1] != 25:
if corner4[1] + corner4[2] != 25:
corner5 = (25 - corner4[0], 25 - corner4[1], 25 - corner4[2])
corner_combinations += 1
print (corner_combinations, corner1, corner2, corner3, corner4, corner5, corner6, corner7, corner8)
Yields this:
2 (1, 14, 22) (2, 16, 20) (4, 15, 18) (6, 13, 19) (19, 12, 6) (21, 10, 7) (23, 9, 5) (24, 11, 3)
3 (1, 14, 22) (2, 17, 19) (4, 13, 20) (7, 15, 16) (18, 10, 9) (21, 12, 5) (23, 8, 6) (24, 11, 3)
4 (1, 14, 22) (2, 17, 19) (4, 15, 18) (5, 13, 20) (20, 12, 5) (21, 10, 7) (23, 8, 6) (24, 11, 3)
5 (1, 14, 23) (3, 15, 19) (4, 16, 18) (5, 12, 20) (20, 13, 5) (21, 9, 7) (22, 10, 6) (24, 11, 2)
6 (1, 14, 23) (3, 16, 18) (4, 15, 19) (5, 12, 20) (20, 13, 5) (21, 10, 6) (22, 9, 7) (24, 11, 2)
7 (1, 15, 21) (2, 17, 19) (3, 14, 20) (7, 13, 18) (18, 12, 7) (22, 11, 5) (23, 8, 6) (24, 10, 4)
8 (1, 15, 21) (2, 17, 19) (3, 16, 18) (5, 13, 20) (20, 12, 5) (22, 9, 7) (23, 8, 6) (24, 10, 4)
9 (1, 15, 22) (2, 14, 21) (5, 16, 17) (6, 12, 19) (19, 13, 6) (20, 9, 8) (23, 11, 4) (24, 10, 3)
10 (1, 15, 22) (2, 14, 21) (5, 16, 17) (6, 13, 18) (19, 12, 7) (20, 9, 8) (23, 11, 4) (24, 10, 3)
11 (1, 15, 22) (2, 16, 19) (4, 14, 20) (7, 12, 18) (18, 13, 7) (21, 11, 5) (23, 9, 6) (24, 10, 3)
12 (1, 15, 22) (2, 16, 19) (4, 14, 20) (7, 13, 17) (18, 12, 8) (21, 11, 5) (23, 9, 6) (24, 10, 3)
13 (1, 15, 22) (2, 17, 18) (4, 14, 20) (6, 12, 19) (19, 13, 6) (21, 11, 5) (23, 8, 7) (24, 10, 3)
14 (1, 16, 20) (2, 14, 22) (4, 15, 18) (6, 13, 19) (19, 12, 6) (21, 10, 7) (23, 11, 3) (24, 9, 5)
15 (1, 16, 21) (2, 13, 22) (5, 15, 18) (6, 14, 17) (19, 11, 8) (20, 10, 7) (23, 12, 3) (24, 9, 4)
16 (1, 16, 21) (2, 15, 20) (3, 17, 18) (6, 12, 19) (19, 13, 6) (22, 8, 7) (23, 10, 5) (24, 9, 4)
17 (1, 16, 21) (2, 17, 18) (3, 15, 20) (6, 12, 19) (19, 13, 6) (22, 10, 5) (23, 8, 7) (24, 9, 4)
18 (1, 17, 19) (2, 14, 22) (4, 13, 20) (7, 15, 16) (18, 10, 9) (21, 12, 5) (23, 11, 3) (24, 8, 6)
19 (1, 17, 19) (2, 14, 22) (4, 15, 18) (5, 13, 20) (20, 12, 5) (21, 10, 7) (23, 11, 3) (24, 8, 6)
20 (1, 17, 19) (2, 15, 21) (3, 14, 20) (7, 13, 18) (18, 12, 7) (22, 11, 5) (23, 10, 4) (24, 8, 6)
21 (1, 17, 19) (2, 15, 21) (3, 16, 18) (5, 13, 20) (20, 12, 5) (22, 9, 7) (23, 10, 4) (24, 8, 6)
22 (1, 17, 20) (2, 13, 22) (4, 15, 19) (7, 14, 16) (18, 11, 9) (21, 10, 6) (23, 12, 3) (24, 8, 5)
23 (1, 17, 20) (2, 14, 21) (3, 16, 19) (7, 12, 18) (18, 13, 7) (22, 9, 6) (23, 11, 4) (24, 8, 5)
24 (1, 17, 20) (2, 16, 19) (3, 14, 21) (7, 12, 18) (18, 13, 7) (22, 11, 4) (23, 9, 6) (24, 8, 5)
25 (1, 18, 19) (2, 14, 21) (3, 15, 20) (8, 12, 17) (17, 13, 8) (22, 10, 5) (23, 11, 4) (24, 7, 6)
26 (1, 18, 19) (2, 14, 21) (3, 15, 20) (8, 13, 16) (17, 12, 9) (22, 10, 5) (23, 11, 4) (24, 7, 6)
27 (1, 18, 19) (2, 15, 20) (3, 14, 21) (8, 12, 17) (17, 13, 8) (22, 11, 4) (23, 10, 5) (24, 7, 6)
28 (1, 18, 19) (2, 15, 20) (3, 14, 21) (8, 13, 16) (17, 12, 9) (22, 11, 4) (23, 10, 5) (24, 7, 6)
So 697 side combinations but only 28 corner combinations.
All I need to do now is to check one against the other somehow. Problem is the position of each side or corner is moveable.