Advertisement
Guest User

Untitled

a guest
Feb 20th, 2018
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.01 KB | None | 0 0
  1. from copy import deepcopy
  2.  
  3. #
  4. # The 576 latin squares on four letters
  5. #
  6. stack = []
  7. result = []
  8.  
  9. # I use sets instead of list to be able to use .discard
  10. latin = [set([x for x in range(4)]) for y in range(16)]
  11. stack.append(deepcopy(latin))
  12.  
  13. def applyConstraints(latin):
  14. for i in range(16):
  15. if len(latin[i]) == 1:
  16. x = list(latin[i])[0]
  17. for j in range(4):
  18. latin[4*(i//4)+j].discard(x)
  19. latin[(i%4)+j*4].discard(x)
  20. latin[i] = set([x])
  21.  
  22.  
  23. while len(stack) != 0:
  24.  
  25. # apply constraints
  26. latin = deepcopy(stack.pop())
  27. latincopy = deepcopy(latin)
  28. applyConstraints(latincopy)
  29. while latincopy != latin:
  30. latin = deepcopy(latincopy)
  31. applyConstraints(latincopy)
  32.  
  33. # store results if done, otherwise branch
  34.  
  35. sizes = [len(x) for x in latin]
  36.  
  37. if min(sizes) == 1 and max(sizes) == 1:
  38. result.append(deepcopy(latin))
  39.  
  40.  
  41. elif min(sizes) != 0:
  42. # identify a set to branch
  43. index = -1
  44. for i in range(16):
  45. if sizes[i] != 1:
  46. index = i
  47. break
  48.  
  49. # branch that set
  50. for x in latin[index]:
  51. latincopy[index] = set([x])
  52. stack.append(deepcopy(latincopy))
  53.  
  54. print(len(result))
  55.  
  56.  
  57.  
  58. #
  59. # The 576 latin squares on 4 letters - using bitwise sets
  60. #
  61. from functools import reduce
  62.  
  63. stack = []
  64. result = []
  65.  
  66. latin = [15 for y in range(16)]
  67. singleton = lambda x : not (x & (x - 1))
  68. stack.append(latin.copy())
  69.  
  70.  
  71.  
  72. def applyConstraints(latin):
  73. for i in range(16):
  74. if singleton(latin[i]):
  75. x = latin[i]
  76. for j in range(4):
  77. latin[4*(i//4)+j] = latin[4*(i//4)+j] & (~x)
  78. latin[(i%4)+j*4] = latin[(i%4)+j*4] & (~x)
  79. latin[i] = x
  80.  
  81.  
  82. while len(stack) != 0:
  83. # pop the next unfinished latin square
  84. latin = stack.pop()
  85.  
  86. # apply constraints
  87. latincopy = latin.copy()
  88. applyConstraints(latincopy)
  89. while latincopy != latin:
  90. latin = latincopy.copy()
  91. applyConstraints(latincopy)
  92.  
  93. # identify singleton sets
  94. singletons = list(map(singleton, latin))
  95.  
  96. # append finished square
  97. appendable = reduce(lambda x, y : x and y, singletons)
  98. if appendable: result.append(latin.copy())
  99. else:
  100. # check if contains empty sets
  101. invalid = map(lambda x : not x, latin)
  102. invalid = reduce(lambda x , y : x or y, invalid)
  103.  
  104. if not invalid:
  105. # identify set with at least two elements
  106. index = singletons.index(False)
  107.  
  108. # branch that set
  109. for x in range(4):
  110. if 2**x & latin[index]:
  111. latincopy[index] = 2**x
  112. stack.append(latincopy.copy())
  113.  
  114. print(len(result))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement