引用多个列表,直到获得正确的组合

时间:2019-04-19 22:24:16

标签: python python-3.x python-3.6 flow-control

已编辑以更新我的代码并给予@MOHAMMED完整响应

如果可以的话,请图片一个立方体。该立方体的每个面都有一组4个数字。多维数据集上的每个数字仅出现一次。

到目前为止,在这里的一些帮助下,我设法编写了一个程序,该程序将这24个数字过滤到一个列表中,该列表中4个数字的每个面孔总计为50,一个面孔上没有对的总数为25,但是每个数字都是正相反(物理上)总共25。

我现在遇到的问题是死角。我有一条规则希望适用于他们。在每个角落碰到的3个数字必须总计为37或38。还有其他一些规则,但是现在让我们坚持下去。

现在,就像一个骰子一样,相反的数字全部加在一起。这意味着,就所有意图而言,我所碰过的每个小组都有对立面,因此,它永远不能与之相邻。

因此,我的程序吐出了第一组符合我的标准的6张面孔。现在我该如何解决呢?

我意识到我只需要使用6张脸中的3张,因为每个数字都与相反的数字(共25张)配对,一旦一个角与规则匹配,相反的数字也应该起作用。

我已将代码简化为仅此问题。

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)

给予

('A','A','A')

假设没有匹配项,则在1,2,3之后还有两个其他可能的组合;分别是1,3,5和1,4,5。

我认为,将1用作一个常数,其他所有变量都通过配对来简化它。

我有2个问题,首先,假设我们的第一个匹配项仅出现在组的最后一个组合中,那么编写代码的最佳方法是什么?

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):

或者:

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):

即使这些代码中的任何一个都可行(由于我是新手,我对这两个代码都感到怀疑),然后我仍需要将这两个数字从与同一组的进一步匹配中删除,并保留它们的顺序。组。

例如,如果规则的第一位选择了组合1,2,4,那么我如何确定只有在这种情况下,后续查询才是正确的(有意义的吗?)

到目前为止,这是我完整的代码。...已编辑

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)

输出(从开始到代码停止无误)为:

1&8 1 2&7 0 3&6 0
...
1&8 8109504 2&7 213792 3&6 5558

因此,角1和8的点击次数为800万,1&8和2&7的点击次数仅为200,000,而1&8、2&7和3&6的点击次数仅为5,000-但不包括4&5)。

这表明要么我尝试的东西无法实现(可能),要么我的代码有问题。

尝试使图更清晰:

  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|
  +----------------------+

============================================= ==============================

响应@Mohammed's代码

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)

我在每张面孔上添加了缺失的“对”(对于4个数字,有6种可能的对组合(AB,AC,AD,BC,BD,CD)。

我重新排列了检查顺序,以首先进行参数最少的检查。

但是我不理解输出,似乎它只是打印从1到n的24个数字的所有组合,而没有应用过滤器。

combinations(range(1,50)更改为combinations(range(1,26)会产生以下输出,并将其更改为combinations(range(1,25)(这将仅利用我要使用的数字(1-24)仅产生第一个下面的输出行。

(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)

============================================= ==============================

添加更多代码:

玩耍我有以下两个充满丑陋的if语句的程序,但希望它们能起作用。

我有

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)

产生:

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)

这:

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)

赞这个:

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)

所以有697个侧面组合,但只有28个角组合。

我现在要做的就是以某种方式检查另一个。问题是每个边或角的位置是可移动的。

3 个答案:

答案 0 :(得分:1)

我对您的问题的处理方式有所不同,但是您可以根据自己的需要调整它的各个方面。希望这可以作为答案,因为它可以解决问题,但我不知道如何找到满足您条件的立方体,除非蛮力。如果已经有一些候选人,则可以稍作修改以仅对那些候选人起作用。

通常,代码的作用就像筛子一样。我选择使用filter()进行繁重的工作,而不是嵌套for循环。这种方法的优点是,更容易通过代码进行推理,可以通过编写过滤器函数来创建新规则,并且可以轻松地稍后对过滤器重新排序以提高性能。

要使代码有意义,您需要查阅此地图。每个候选组合都是一个包含24个元素的元组,因此索引从0到23。A= 0,B = 1,C = 2,...,X =23。我仔细检查了所有过滤器功能使用正确的索引,但您可能需要仔细检查。

编辑:我已经通过您的修复更正了结对功能,并将组合更改为排列。由于每个数字都映射到多维数据集上的特定位置,因此顺序很重要。这就是为什么groups(range(1,25),24)只产生一个组合的原因。只有一个由24个数字组成的无序集合,其中包含数字1到24。这次我也手动创建了过滤器链,因为链接功能在这种情况下似乎不起作用。

          +-----+
          | A B |
          | C D |
    +-----+-----+-----+-----+
    | E F | G H | I J | K L |
    | M N | O P | Q R | S T |
    +-----+-----+-----+-----+
          | U V |
          | W X |
          +-----+
from itertools import permutations

# Filter functions
# ------------

# 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 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 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)

candidates = permutations(range(1,25), 24)
cubes = filter(check_pairs,
               filter(check_corners,
                      filter(check_corners,
                             filter(check_sides, candidates))))
for cube in cubes:
    print(cube)

此代码的作用:

  1. permutations以所有可能的顺序生成一个从1到24的24个整数的元组的迭代器。这意味着它将像可能的候选多维数据集列表一样工作,但是仅在被询问时才创建每个元组,而不是事先创建。这限制了内存使用。每个组合就像(n1,n2,n3,... n24)。该元组的每个成员对应于多维数据集上的一个数字。
  2. 链式过滤器的作用就像一个筛子。它从最里面的过滤器开始,一直到出口。每个内部过滤器仅传递那些满足过滤功能所有条件的排列。
  3. 如果括号内的所有比较均为all(),则True会返回True。括号内的表达式称为generator expression
  4. cubes包含一个链接的迭代器,该迭代器按照您在列表中看到的顺序检查条件。如果您确定哪些消除了最多的候选多维数据集,则可以提高性能。您在连锁店开始时淘汰的候选人越多,沿线浪费的时间就越少。
  5. for循环是第一次运行任何检查代码,因为当循环向cubes询问某项时,cubes必须询问filter(check_pairs, ...)必须一直问filter(check_sides, ...)。因此,check_sides是最深的级别,这意味着它实际上是首先执行的 first 比较。
  6. 每次cubes吐出一个元组,其值满足过滤器函数指定的所有条件,for循环将其打印出来。

最后,如果您跟踪已经尝试了多少组合并且程序崩溃或必须暂停,请查看here,以获取有关如何跳至可迭代项的第n个项目的示例。 combinations()

答案 1 :(得分:0)

为了清楚起见,将其添加为答案,而不是再次编辑问题。

因此,使用我的边角代码,我在创建的两个列表(边角和边)上进行了列表比较。

代码现在似乎可以工作了。太杂乱了,但是有效(我认为)

谢谢您的帮助。

from itertools import combinations

# program to distribute 24 numbers across the 6 sides of a cube
# there will be 4 numbers to a side
# and 3 numbers at each corner where 3 sides meet
#  every number and its physical opposite must sum to 25.
# this means only the 1st 4 corners and 3 sides have to be worked out.  
# as the opposites will automatically obey the rules. 
# no pairs of numbers in a corner or on a side may equal 25
# the sum of a side must equal 50
# the sum of a corner must equal 37 or 38
# the sum of 2 corners connected by an edge must equal 75
# corners opposite each other on a side must be equal

corner_combinations = 0 # a simple counter
side_combinations = 0 # a simple counter
side_numbers_all = list(range(1,25)) # list of all numbers from 1 to 24
corner_numbers_all = list(range(1,25)) # list of all numbers from 1 to 24

# find the first corner 

for corner_a in combinations((corner_numbers_all[1:24]), 2): # find combinations of 2 numbers from 2 to 23 (not using 1 or 24 as 1 is the first constant, and 24 is its direct opposite)


  if 36 < corner_numbers_all[0] + sum(corner_a) < 39: # check if the corner using 1 (the constant mentiined above) and the pair of numbers from the combination sum to 37 or 38
    corner1 = (corner_numbers_all[0], corner_a[0], corner_a[1]) # create a new corner list with the constant and the combination
    if 25 not in (corner1[0] + corner1[1], corner1[0] + corner1[2], corner1[1] + corner1[2]): # check that all possible pairings in the new list do not sum to 25
      corner8 = (25 - corner1[0], 25 - corner1[1], 25 - corner1[2]) # create a new corner list that is the opposite of the current list.

      corner_numbers_remaining = list(set(corner_numbers_all) - set(corner1) - set(corner8)) # create a new list of numbers from the 1st list minus the 2 corner lists just created

# find the second corner, rules as above
      for corner_b in combinations((corner_numbers_remaining[1:18]), 2):
        if 36 < corner_numbers_remaining[0] + sum(corner_b) < 39:
          corner2 = (corner_numbers_remaining[0], corner_b[0], corner_b[1])
          if sum(corner1) + sum(corner2) == 75: # checks to see if the sum of the first and second corners is 75
            if 25 not in (corner2[0] + corner2[1], corner2[0] + corner2[2], corner2[1] + corner2[2]):
              corner7 = (25 - corner2[0], 25 - corner2[1], 25 - corner2[2])

              corner_numbers_remaining2 = list(set(corner_numbers_remaining) - set(corner2) - set(corner7))

# find third corner, as abive
              for corner_c in combinations((corner_numbers_remaining2[1:12]), 2):
                if 36 < corner_numbers_remaining2[0] + sum(corner_c) < 39:
                  corner3 = (corner_numbers_remaining2[0], corner_c[0], corner_c[1])
                  if sum(corner3) == sum(corner1): # check to see if the sum of the first corner is the same as the sum of the third corner
                    if (corner3[0] + corner3[1] and corner3[0] + corner3[2] and corner3[1] + corner3[2]) != 25:
                      corner6 = (25 - corner3[0], 25 - corner3[1], 25 - corner3[2])

                      corner_numbers_remaining3 = list(set(corner_numbers_remaining2) - set(corner3) - set(corner6))

# find fourth corner, as per second corner
                      for corner_d in combinations((corner_numbers_remaining3[1:6]), 2):
                        if 36 < corner_numbers_remaining3[0] + sum(corner_d) < 39:
                          corner4 = (corner_numbers_remaining3[0], corner_d[0], corner_d[1])
                          if sum(corner1) + sum(corner4) ==75:
                            if (corner4[0] + corner4[1] and corner4[0] + corner4[1] and corner4[1] + corner4[2]) != 25:
                              corner5 = (25 - corner4[0], 25 - corner4[1], 25 - corner4[2])

                              corner_combinations += 1 # count how many combinations of corners meet the criteria.

# find first side, as per first corner

                              for side_a in combinations((side_numbers_all[1:24]),3): # 3 number combination this time, still dropping 1 and 24
                                if side_numbers_all[0] + sum(side_a) == 50: # check constant and combination sum to 50
                                  if 25 not in (side_numbers_all[0] + side_a[0], side_numbers_all[0] + side_a[1], side_numbers_all[0] + side_a[2], side_a[0] + side_a[1], side_a[0] + side_a[2], side_a[1] + side_a[2]): # check no pairs of numbers sum to 25
                                    side1 = (side_numbers_all[0], side_a[0], side_a[1], side_a[2]) # createvfirst side list
                                    if len(set(side1).intersection(corner1)) <= 1 and len(set(side1).intersection(corner2)) <= 1 and len(set(side1).intersection(corner3)) <= 1 and len(set(side1).intersection(corner4)) <= 1 and len(set(side1).intersection(corner5)) <= 1 and len(set(side1).intersection(corner6)) <= 1 and len(set(side1).intersection(corner7)) <= 1 and len(set(side1).intersection(corner8)) <= 1: # check first side against all corners.  Each number in side may only exist in one corner.
                                      side6 = (25-side1[0], 25-side1[1], 25-side1[2], 25-side1[3]) # create the opposite side

# find second side as above
                                      side_numbers_remaining = list(set(side_numbers_all) - set(side1) - set(side6))
                                      for side_b in combinations(side_numbers_remaining[1:16],3):
                                        if side_numbers_remaining[0] + sum(side_b) == 50:
                                          if 25 not in (side_numbers_remaining[0] + side_b[0], side_numbers_remaining[0] + side_b[1], side_numbers_remaining[0] + side_b[2], side_b[0] + side_b[1], side_b[0] + side_b[2], side_b[1] + side_b[2]):
                                            side2 = (side_numbers_remaining[0], side_b[0], side_b[1], side_b[2])
                                            if len(set(side2).intersection(corner1)) <= 1 and len(set(side2).intersection(corner2)) <= 1 and len(set(side2).intersection(corner3)) <= 1 and len(set(side2).intersection(corner4)) <= 1 and len(set(side2).intersection(corner5)) <= 1 and len(set(side2).intersection(corner6)) <= 1 and len(set(side2).intersection(corner7)) <= 1 and len(set(side2).intersection(corner8)) <= 1:
                                              side5 = (25-side2[0], 25-side2[1], 25-side2[2], 25-side2[3])
                                              side_numbers_remaining2 = list(set(side_numbers_remaining) - set(side2) - set(side5))
                                              for side_c in combinations(side_numbers_remaining2[1:8],3):
                                                if side_numbers_remaining2[0] + sum(side_c) == 50:
                                                  if 25 not in (side_numbers_remaining2[0] + side_c[0], side_numbers_remaining2[0] + side_c[1], side_numbers_remaining2[0] + side_c[2], side_c[0] + side_c[1], side_c[0] + side_c[2], side_c[1] + side_c[2]):
                                                    side3 = (side_numbers_remaining2[0], side_c[0], side_c[1], side_c[2])
                                                    if len(set(side3).intersection(corner1)) <= 1 and len(set(side3).intersection(corner2)) <= 1 and len(set(side3).intersection(corner3)) <= 1 and len(set(side3).intersection(corner4)) <= 1 and len(set(side3).intersection(corner5)) <= 1 and len(set(side3).intersection(corner6)) <= 1 and len(set(side3).intersection(corner7)) <= 1 and len(set(side3).intersection(corner8)) <= 1:
                                                      side4 = (25-side3[0], 25-side3[1], 25-side3[2], 25-side3[3])

                                                      side_combinations += 1 # count how many sides combinations meet the criteria 

# print result
                                                      print ("corner combinations:", corner_combinations)
                                                      print (corner1,"=", sum(corner1), corner2,"=", sum(corner2), corner3,"=", sum(corner3), corner4,"=", sum(corner4), corner5,"=", sum(corner5), corner6,"=", sum(corner6), corner7,"=", sum(corner7), corner8,"=", sum(corner8))
                                                      print ("side combinations:", side_combinations)
                                                      print (side1,"=", sum(side1), side2,"=", sum(side2), side3,"=", sum(side3), side4,"=", sum(side4), side5,"=", sum(side5), side6,"=", sum(side6))                                              

答案 2 :(得分:0)

我刚刚重新开始这个项目 - 在我恢复我的 SOF 帐户之前,我已经忘记了上述所有内容。

我在此期间创建的是,我认为,这是一种破解此问题的蛮力尝试。代码大约需要 5-10 分钟才能完成并生成一个组合。

Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 21:26:53) [MSC v.1916 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
>>> 
====================== RESTART: C:\Users\escri\face1.py ======================
1: [1, 12, 16, 21][18, 10, 3, 19][11, 17, 20, 2][23, 5, 8, 14][6, 22, 15, 7][4, 9, 13, 24]
There are 1 combinations
>>> 

代码如下:

r = range(2, 23)   # +-------------+-------------+-------------+
n = 0              # | C6:2--------| F2:0   F2:1 |--------C5:2 |
                   # | | F6:1      | C6:1   C5:1 |      F6:0 | |
f1 = [1,0,0,0]     # | |           |             |           | |
f2 = [0,0,0,0]     # | |           | F2:3   F2:2 |           | |
f3 = [0,0,0,0]     # | |           | C1:1   C2:1 |           | |
f4 = [0,0,0,0]     # +-------------+-------------+-------------+
f5 = [0,0,0,0]     # | F3:0   F3:1 | F1:0   F1:1 | F4:0   F4:1 |
f6 = [0,0,0,24]    # | C6:0   C1:2 | C1:0   C2:0 | C2:2   C5:0 |
                   # |             |             |             |
c1 = [1,0,0]       # | F3:3   F3:2 | F1:3   F1:2 | F4:3   F4:2 |
c2 = [0,0,0]       # | C7:0   C4:2 | C4:0   C3:0 | C3:2   C8:0 |
c3 = [0,0,0]       # +-------------+-------------+-------------+
c4 = [0,0,0]       # | |           | F5:2   F5:3 |           | |
c5 = [0,0,0]       # | |           | C4:1   C3:1 |           | |
c6 = [0,0,0]       # | |           |             |           | |
c7 = [0,0,0]       # | | F6:2      | F5:1   F5:0 |      F6:3 | |
c8 = [0,0,24]      # | C7:2--------| C7:1   C8:1 |--------C8:2 |
                   # +-------------+-------------+-------------+

for xa in r:
  f1[1] = xa
  f6[2] = 25 - xa
  for ya in r:
    if ya != xa and ya + xa != 25:
      f1[2] = ya
      f6[1] = 25 - ya
      for za in r:
        if za != xa and za + xa != 25 and za != ya and za + ya != 25:
          f1[3] = za
          f6[0] = 25 - za
          
          if sum(f1) == 50:
            c2[0] = f1[1]
            c7[2] = f6[2]
            c3[0] = f1[2]
            c6[2] = f6[1]
            c4[0] = f1[3]
            c5[2] = f6[0]
            
            for wb in r:
              if wb not in f1 and wb not in f6:
                f2[0] = wb
                f5[3] = 25 - wb
                for xb in r:
                  if xb not in f1 and xb not in f6 and xb != wb and xb + wb != 25:
                    f2[1] = xb
                    f5[2] = 25 - xb
                    for yb in r:
                      if yb not in f1 and yb not in f6 and yb != wb and yb + wb !=25 and yb != xb and yb + xb != 25:
                        f2[2] = yb
                        f5[1] = 25 - yb
                        for zb in r:
                          if zb not in f1 and zb not in f6 and zb != wb and zb + wb !=25 and zb != xb and zb + xb != 25 and zb != yb and zb + yb != 25:
                            f2[3] = zb
                            f5[0] = 25 - zb
                            
                            if sum(f2) == 50:
                              c6[1] = f2[0]
                              c3[1] = f5[3]
                              c5[1] = f2[1]
                              c4[1] = f5[2]
                              c2[1] = f2[2]
                              c7[1] = f5[1]
                              c1[1] = f2[3]
                              c8[1] = f5[0]
                              
                              for wc in r:
                                if wc not in f1 and wc not in f2 and wc not in f5 and wc not in f6:
                                  f3[0] = wc
                                  f4[3] = 25 - wc
                                  for xc in r:
                                    if xc not in f1 and xc not in f2 and xc not in f5 and xc not in f6 and xc != wc and xc + wc != 25:
                                      f3[1] = xc
                                      f4[2] = 25 - xc
                                      for yc in r:
                                        if yc not in f1 and yc not in f2 and yc not in f5 and yc not in f6 and yc != wc and yc + wc != 25 and yc != xc and yc + xc != 25:
                                          f3[2] = yc
                                          f4[1] = 25 - yc
                                          for zc in r:
                                            if zc not in f1 and zc not in f2 and zc not in f5 and zc not in f6 and zc != wc and zc + wc != 25 and zc != xc and zc + xc != 25 and zc != yc and zc + yc != 25:
                                              f3[3] = zc
                                              f4[0] = 25 - zc
                                              
                                              if sum(f3) == 50:
                                                c6[0] = f3[0]
                                                c3[2] = f4[3]
                                                c1[2] = f3[1]
                                                c8[0] = f4[2]
                                                c7[0] = f3[2]
                                                c5[0] = f4[1]
                                                c4[2] = f3[3]
                                                c2[2] = f4[0]
                                                
                                                if sum(c1) == 37 or sum(c1) == 38:
                                                  if sum(c1) + sum(c2) == 75 and sum(c1) + sum(c4) == 75 and sum(c1) == sum(c3) and sum(c1) + sum(c8) == 75:
                                                    n += 1
                                                    print(f"{n}: {f1}{f2}{f3}{f4}{f5}{f6}")
print(f"There are {n} combinations")