Advertisement
Guest User

magic square solver

a guest
Oct 14th, 2012
413
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.18 KB | None | 0 0
  1. #!/usr/bin/python
  2.  
  3. # just edit INIT with a list of tuples in the form (i,j,n) for the fixed numbers
  4. # where i j represent row an col numbers (from 0 to 3)
  5. # and n is the number in that position
  6. # example INIT=((2,0,8),(2,3,11))
  7. # save and run this script with python
  8. INIT= ()
  9.  
  10. class Matrix:
  11.  
  12.     sum = 34
  13.  
  14.     def __init__(self, numeros = ()):
  15.         self.data =  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
  16.         self.fijos = []
  17.         if isinstance(numeros, tuple):
  18.             for t in numeros:
  19.                 i = t[0]
  20.                 if len(t) == 3: i = i*4 + t[1]
  21.                 n = t[len(t)-1]
  22.                 self.data[i] = n
  23.                 self.fijos.append(i)
  24.  
  25.     def __str__(self):
  26.         r = ''
  27.         for i in range(4):
  28.             r += '[ %02d %02d %02d %02d ]' % (self.data[0+i*4], self.data[1+i*4], self.data[2+i*4], self.data[3+i*4])
  29.             r += '\n'
  30.         return r
  31.  
  32.     def __repr__(self):
  33.         r = ''
  34.         for i in range(4):
  35.             r += '[ %02d %02d %02d %02d ]' % (self.data[0+i*4], self.data[1+i*4], self.data[2+i*4], self.data[3+i*4])
  36.             r += '\n'
  37.         return r
  38.    
  39.     def libre(self):
  40.         if 0 in self.data:
  41.             return self.data.index(0)
  42.         else:
  43.             return -1
  44.  
  45. class Numeros:
  46.  
  47.     def __init__(self, numeros = ()):
  48.         self.data = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
  49.         if isinstance(numeros, tuple):
  50.             for t in numeros:
  51.                 n = t[len(t)-1]
  52.                 if n in self.data: self.data.remove(n)
  53.  
  54.     def __str__(self):
  55.         r = '[ '
  56.         for i in self.data:
  57.             r += '%02d ' % n
  58.         r += ']'
  59.         return r
  60.  
  61.     def __repr__(self):
  62.         r = '[ '
  63.         for i in self.data:
  64.             r += '%02d ' % n
  65.         r += ']'
  66.         return r
  67.  
  68.     def remove(self, n):
  69.         if n in self.data:
  70.             self.data.remove(n)
  71.             return n
  72.    
  73.     def insert(self, n):
  74.         for i in range(len(self.data)):
  75.             if self.data[i] > n:
  76.                 self.data.insert(i,n)
  77.                 return
  78.         self.data.append(n)
  79.  
  80. class Solver:
  81.     def __init__(self, m, n):
  82.         if isinstance(m,Matrix):
  83.             self.matrix = m
  84.         else:
  85.             self.matrix = Matrix()
  86.         if isinstance(n,Numeros):
  87.             self.numeros = n
  88.         else:
  89.             self.numeros = Numeros()
  90.    
  91.     def testRow(self, i):
  92.         l = [self.matrix.data[i*4+x] for x in range(4)]
  93.         if 0 in l: return 0
  94.         if sum(l) == Matrix.sum: return 1
  95.         return -1
  96.    
  97.     def testCol(self, i):
  98.         l = [self.matrix.data[x*4+i] for x in range(4)]
  99.         if 0 in l: return 0
  100.         if sum(l) == Matrix.sum: return 1
  101.         return -1
  102.  
  103.     def testDiag(self, t):
  104.         l = [self.matrix.data[x] for x in (0,5,10,15)] if not t else [self.matrix.data[x] for x in (3,6,9,12)]
  105.         if 0 in l: return 0
  106.         if sum(l) == Matrix.sum: return 1
  107.         return -1
  108.    
  109.     def test(self, n):
  110.         res = 0
  111.         i = n // 4
  112.         j = n % 4
  113.         resR = self.testRow(i)
  114.         resC = self.testCol(j)
  115.         resD = 1
  116.         if n in (0,5,10,15): resD = self.testDiag(0)
  117.         if n in (3,6,9,12): resD = self.testDiag(1)
  118.         if -1 in (resR, resC, resD): return -1
  119.         if (resR == resC == resD == 1) and not 0 in self.matrix.data: return 1
  120.         return 0
  121.  
  122.     def resuelve(self):
  123.         aux = self.numeros.data[:]
  124.         i = self.matrix.libre()
  125.         for n in aux:
  126.             self.matrix.data[i] = n
  127.             self.numeros.remove(n)
  128.             res = self.test(i)
  129.             if res == 0: res = self.resuelve()
  130.             if res == 1: return 1
  131.             self.numeros.insert(n)
  132.             self.matrix.data[i] = 0
  133.            
  134.  
  135. #main
  136. matrix = Matrix(INIT)
  137. numeros = Numeros(INIT)
  138. solver = Solver(matrix, numeros)
  139. solver.resuelve()
  140. print(solver.matrix)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement