Advertisement
Guest User

exact cover by 3sets

a guest
Nov 29th, 2020
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.37 KB | None | 0 0
  1. import sympy
  2. import random
  3. from itertools import permutations
  4.  
  5. # Only input lists with 3-elements.
  6. # Lists should be treated as sets.
  7. s = [1,2,3,4,5,6]
  8. c = [[1,4,3],[4,6,5],[1,3,2]]
  9.  
  10.  
  11. miss = []
  12. delete = []
  13. remove = []
  14. remove_t=[]
  15. no = 0
  16. def input_validation():
  17.     # checking for missing elements.
  18.     no = 0
  19.     for a in range(0, len(c)):
  20.         for b in range(0, len(c[a])):
  21.             miss.append(c[a][b])
  22.     for d in s:
  23.         if d not in miss:
  24.             print('no', d)
  25.             no = 1
  26.             break
  27.     if no == 1:
  28.         quit()
  29.     # Throw out unwanted orderings of sub-lists    
  30.     for a in range(0, len(c)):
  31.         for i in permutations(c[a], 3):
  32.             if list(i) in c[a:]:
  33.                 if list(i) != c[a]:
  34.                     delete.append(list(i))
  35.     for a in range(0, len(delete)):
  36.         if delete[a] in c:
  37.             del c[c.index(delete[a])]
  38.     # Lists are treated as sets, so lists
  39.     # with repeating elements is thrown out        
  40.     for rem in range(0, len(c)):
  41.         if len(c[rem]) != len(set(c[rem])):
  42.             remove.append(c[rem])
  43.     for rem_two in range(0, len(remove)):
  44.         if remove[rem_two] in c:
  45.             del c[c.index(remove[rem_two])]
  46.     # Throw out lists that have elements that do
  47.     # not exist in s.
  48.     for j in range(0, len(c)):
  49.         for jj in range(0, len(c[j])):
  50.             if any(elem not in s for elem in c[j]):
  51.                 remove_t.append(c[j])
  52.     for rem_two in range(0, len(remove_t)):
  53.         if remove_t[rem_two] in c:
  54.             del c[c.index(remove_t[rem_two])]
  55.        
  56.  
  57.  
  58.            
  59.  
  60. input_validation()
  61.  
  62. # This reduction aims at reducing the running time
  63. # within the length of the input.
  64.  
  65. # This is a bijective mapping of values in both C & S to their
  66. # index-location values.
  67.  
  68. def reduction_t():
  69.     s_copy = s.copy()
  70.     for a in range(0, len(s)):
  71.         s[a] = a
  72.     for b in range(0, len(c)):
  73.         for bb in range(0, len(c[b])):
  74.             c[b][bb] = s_copy.index(c[b][bb])
  75.  
  76. # Use primes to help spread values apart.
  77. # So that one value shouldn't replace another.
  78. # Causing a false positive.
  79.  
  80. # (eg. C = [3], [3,4] == 10, and so
  81. # does S = 1,2,3,4. But 1 & 2 are missing.)
  82. def reduction_r():
  83.     s_copy = s.copy()
  84.     prime = 1
  85.     for a in range(0, len(s)):
  86.         while True:
  87.             prime = prime + 1
  88.             if sympy.isprime(prime) == True:
  89.                 if prime > a+1:
  90.                     if prime not in s:
  91.                         m = random.randint(2, len(c))
  92.                         if prime*m not in s:
  93.                             s[a] = prime*m
  94.                             break
  95.     for b in range(0, len(c)):
  96.         for bb in range(0, len(c[b])):
  97.             c[b][bb] = s[c[b][bb]]
  98.  
  99.  
  100. reduction_t()
  101. reduction_r()
  102.  
  103.  
  104.  
  105. r = []
  106. for a in range(0, len(c)):
  107.     r.append(sum(c[a]))
  108.  
  109. # Remove lists with repeating values
  110. r = [r[x] for x in range(len(r)) if not(r[x] in r[:x])]
  111. # k is our target-sum for SubsetSum function
  112. k = sum(s)
  113.  
  114. # Courtesy to google search.
  115. # I did not write this code
  116. # below.
  117. def isSubsetSum(set, n, sum):
  118.      
  119.     # The value of subset[i][j] will be
  120.     # true if there is a
  121.     # subset of set[0..j-1] with sum equal to i
  122.     subset =([[False for i in range(sum + 1)]
  123.             for i in range(n + 1)])
  124.      
  125.     # If sum is 0, then answer is true
  126.     for i in range(n + 1):
  127.         subset[i][0] = True
  128.          
  129.     # If sum is not 0 and set is empty,
  130.     # then answer is false
  131.     for i in range(1, sum + 1):
  132.          subset[0][i]= False
  133.              
  134.     # Fill the subset table in botton up manner
  135.     for i in range(1, n + 1):
  136.         for j in range(1, sum + 1):
  137.             if j<set[i-1]:
  138.                 subset[i][j] = subset[i-1][j]
  139.             if j>= set[i-1]:
  140.                 subset[i][j] = (subset[i-1][j] or
  141.                                 subset[i - 1][j-set[i-1]])
  142.      
  143.     # uncomment this code to print table
  144.     # for i in range(n + 1):
  145.     # for j in range(sum + 1):
  146.     # print (subset[i][j], end =" ")
  147.     # print()
  148.     return subset[n][sum]
  149.          
  150. # Driver code
  151. if __name__=='__main__':
  152.     set = r
  153.     sum = k
  154.     n = len(set)
  155.     if (isSubsetSum(set, n, sum) == True):
  156.         print("There should be an Exact Cover with sets of 3.")
  157.     else:
  158.         print("No")
  159.          
  160. # This code is contributed by
  161. # sahil shelangia.
  162.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement