import pickle
class ChompBoard():
def __init__(self, _rows = []):
if all(_rows[i]>=_rows[i+1] for i in range(len(_rows)-1)):
self._rows = _rows
while self._rows != [] and self._rows[len(self._rows)-1] == 0:
self._rows.pop()
else:
raise TypeError("list elements must be non-increasing")
def __eq__(self, other):
return self._rows == other._rows
def __repr__(self):
return str(self._rows)
def name(self):
return str(self._rows)
def rows(self):
return copy(self._rows)
def columns(self):
M = self.matrix()
return [sum(x) for x in M.columns()]
def number_of_rows(self):
return len(self._rows)
def columns(self):
M = self.matrix()
return [sum(x) for x in M.columns()]
def number_of_columns(self):
if self.number_of_rows() == 0:
return 0
else:
return self._rows[0]
def number_of_cookies(self):
return sum(self._rows)
def full_rectangle(self):
return self.number_of_columns() * self.number_of_rows()
def empty_space(self):
return self.full_rectangle() - self.number_of_cookies()
def full_square(self):
return max(self.number_of_rows()**2,self.number_of_columns()**2)
def rows_of_different_length(self):
M = self.matrix()
return M.rank()
def columns_of_different_length(self):
return self.rows_of_different_length()
def duplicate_rows(self):
return abs(self.number_of_rows() - self.rows_of_different_length())
def duplicate_columns(self):
return abs(self.number_of_columns() - self.columns_of_different_length())
def squared_matrix(self):
M = self.matrix()
M = self.matrix()
if self._rows == []:
return matrix(0,0,[])
M = matrix(m,m,[0]*(m*m))
for i in range(len(self._rows)):
for j in range(self._rows[i]):
M[i,j] = 1
return M
def determinant(self):
M = self.squared_matrix()
return det(M)
def trace_square(self):
M = self.squared_matrix()
return M.trace()
def squareness(self):
return abs(self.number_of_rows()-self.number_of_columns())
def matrix(self):
if self._rows == []:
return matrix(0,0,[])
m = len(self._rows)
n = self._rows[0]
M = matrix(m,n,[0]*(m*n))
for i in range(m):
for j in range(self._rows[i]):
M[i,j] = 1
return M
def columns_of_different_length(self):
return self.rows_of_different_length()
def duplicate_rows(self):
return self.number_of_rows() - self.rows_of_different_length()
def duplicate_columns(self):
return self.number_of_columns() - self.rows_of_different_length()
def columns_of_different_length(self):
def max_eigenvalue(self):
if self._rows == []:
return 0
M = self.squared_matrix()
L = M.eigenvalues()
return max([real_part(x) for x in L])
def min_eigenvalue(self):
if self._rows == []:
return 0
M = self.squared_matrix()
L = M.eigenvalues()
return min([real_part(x) for x in L])
def max_eigenvalue(self):
if self._rows == []:
return 0
M = self.squared_matrix()
def max_eigenvalue(self):
if self._rows == []:
return 0
M = self.squared_matrix()
L = M.eigenvalues()
return max([real_part(x) for x in L])
def min_eigenvalue(self):
if self._rows == []:
return 0
M = self.squared_matrix()
L = M.eigenvalues()
return min([real_part(x) for x in L])
def duplicate_rows(self):
def max_eigenvalue(self):
if self._rows == []:
return 0
M = self.squared_matrix()
L = M.eigenvalues()
return max([real_part(x) for x in L])
def min_eigenvalue(self):
if self._rows == []:
return 0
def max_eigenvalue(self):
if self._rows == []:
return 0
M = self.squared_matrix()
L = M.eigenvalues()
return max([real_part(x) for x in L])
def min_eigenvalue(self):
if self._rows == []:
return 0
M = self.squared_matrix()
L = M.eigenvalues()
return min([real_part(x) for x in L])
def duplicate_rows(self):
def max_eigenvalue(self):
if self._rows == []:
return 0
M = self.squared_matrix()
L = M.eigenvalues()
return max([real_part(x) for x in L])
def min_eigenvalue(self):
if self._rows == []:
return 0
M = self.squared_matrix()
L = M.eigenvalues()
return min([real_part(x) for x in L])
def duplicate_columns(self):
n = self._rows[0]
M = matrix(m,n,[0]*(m*n))
for i in range(m):
for j in range(self._rows[i]):
M[i,j] = 1
return M
def eigen_max_positive(self):
M = self.squared_matrix()
L = M.eigenvalues()
if Lreal != []:
return max(Lreal)
else:
return 0
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
number = 0
M= self.damage_matrix()
for i in range(M_rows):
for j in range(M_columns):
number = number + M[i,j]
return number
def row_gcd(self):
return gcd([sum(x) for x in self.rows()])
def row_product(self):
if self.rows() == []:
return 0
return prod(self.rows())
def column_product(self):
if self.name() == "[]":
return 0
return prod(self.columns()) newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
return M
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def eigen(self):
M = self.squared_matrix()
L = M.eigenvalues()
return [x for x in L if x.is_real()]
def damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
number = 0
M= self.damage_matrix()
for i in range(M_rows):
for j in range(M_columns):
number = number + M[i,j]
return number
def row_gcd(self):
return gcd(self.rows())
def row_lcm(self):
return lcm(self.rows())
M = self.squared_matrix()
L = M.eigenvalues()
return min([real_part(x) for x in L])
return self.number_of_rows() - self.rows_of_different_length()
def duplicate_columns(self):
n = self._rows[0]
M = matrix(m,n,[0]*(m*n))
for i in range(m):
for j in range(self._rows[i]):
M[i,j] = 1
return M
def eigen_max_positive(self):
M = self.squared_matrix()
L = M.eigenvalues()
if Lreal != []:
return max(Lreal)
else:
return 0s a squared damage matrix
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
number = 0
M= self.damage_matrix()
for i in range(M_rows):
for j in range(M_columns):
number = number + M[i,j]
return number
def row_gcd(self):
return gcd([sum(x) for x in self.rows()])
def row_product(self):
if self.rows() == []:
return 0
return prod(self.rows())
def column_product(self):
if self.name() == "[]":
return 0
return prod(self.columns()) newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
return M
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def eigen(self):
M = self.squared_matrix()
L = M.eigenvalues()
return [x for x in L if x.is_real()]
def damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
number = 0
M= self.damage_matrix()
for i in range(M_rows):
for j in range(M_columns):
number = number + M[i,j]
return number
def row_gcd(self):
return gcd(self.rows())
def row_lcm(self):
return lcm(self.rows())
L = M.eigenvalues()
return max([real_part(x) for x in L])
def min_eigenvalue(self):
if self._rows == []:
return 0
def max_eigenvalue(self):
if self._rows == []:
return 0
M = self.squared_matrix()
L = M.eigenvalues()
return max([real_part(x) for x in L])
def min_eigenvalue(self):
if self._rows == []:
return 0
M = self.squared_matrix()
L = M.eigenvalues()
return min([real_part(x) for x in L])
return self.rows_of_different_length()
def duplicate_rows(self):
def max_eigenvalue(self):
if self._rows == []:
return 0
M = self.squared_matrix()
L = M.eigenvalues()
return max([real_part(x) for x in L])
def min_eigenvalue(self):
if self._rows == []:
return 0
M = self.squared_matrix()
L = M.eigenvalues()
return min([real_part(x) for x in L])
return self.number_of_rows() - self.rows_of_different_length()
def duplicate_columns(self):
n = self._rows[0]
M = matrix(m,n,[0]*(m*n))
for i in range(m):
for j in range(self._rows[i]):
M[i,j] = 1
return M
def eigen_max_positive(self):
M = self.squared_matrix()
L = M.eigenvalues()
if Lreal != []:
return max(Lreal)
else:
return 0s a squared damage matrix
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
number = 0
M= self.damage_matrix()
for i in range(M_rows):
for j in range(M_columns):
number = number + M[i,j]
return number
def row_gcd(self):
return gcd([sum(x) for x in self.rows()])
def row_product(self):
if self.rows() == []:
return 0
return prod(self.rows())
def column_product(self):
if self.name() == "[]":
return 0
return prod(self.columns()) newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
return M
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def eigen(self):
M = self.squared_matrix()
L = M.eigenvalues()
return [x for x in L if x.is_real()]
def damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
number = 0
M= self.damage_matrix()
for i in range(M_rows):
for j in range(M_columns):
number = number + M[i,j]
return number
def row_gcd(self):
return gcd(self.rows())
def row_lcm(self):
return lcm(self.rows())
M = self.squared_matrix()
L = M.eigenvalues()
return min([real_part(x) for x in L])
return self.number_of_rows() - self.rows_of_different_length()
def duplicate_columns(self):
n = self._rows[0]
M = matrix(m,n,[0]*(m*n))
for i in range(m):
for j in range(self._rows[i]):
M[i,j] = 1
return M
def eigen_max_positive(self):
M = self.squared_matrix()
L = M.eigenvalues()
if Lreal != []:
return max(Lreal)
else:
return 0s a squared damage matrix
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
try:
value = conj.evaluate(board)
if value == False:
Pcounterexamples.append(board.name())
print "{} is a counterexample to: {}".format(board.name(),conj)
return board
except:
print "error with evaluating: {} for {}".format(conj,board.name())
L = find_reachable_P_positions(ChompBoard([column_limit]*row_limit))
for board in L:
try:
value = conj.evaluate(board)
if value == False:
Pcounterexamples.append(board.name())
print "{} is a counterexample to: {}".format(board.name(),conj)
return board
except:
print "error with evaluating: {} for {}".format(conj,board.name()) M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
number = 0
M= self.damage_matrix()
for i in range(M_rows):
for j in range(M_columns):
number = number + M[i,j]
return number
def row_gcd(self):
return gcd([sum(x) for x in self.rows()])
def row_product(self):
if self.rows() == []:
return 0
return prod(self.rows())
def column_product(self):
if self.name() == "[]":
return 0
return prod(self.columns()) newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
return M
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def eigen(self):
M = self.squared_matrix()
L = M.eigenvalues()
return [x for x in L if x.is_real()]
def damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
number = 0
M= self.damage_matrix()
for i in range(M_rows):
for j in range(M_columns):
number = number + M[i,j]
return number
def row_gcd(self):
return gcd(self.rows())
def row_lcm(self):
return lcm(self.rows())
def eigen_min_positive(self):
M = self.squared_matrix()
L = M.eigenvalues()
Lreal = [real_part(x) for x in L if real_part(x) > 0]
if Lreal != []:
return max(Lreal)
else:
return 0
def damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M_max = max(self.number_of_columns(),self.number_of_rows())
M_max = max(self.number_of_columns(),self.number_of_rows())
M_max = max(self.number_of_columns(),self.number_of_rows())
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_rows,M_columns,[0]*(M_rows*M_columns))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def squared_damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
M_max = max(self.number_of_columns(),self.number_of_rows())
M = matrix(M_max,M_max,[0]*(M_max**2))
oldcookies = self.number_of_cookies()
for i in range(M_rows):
for j in range(M_columns):
newboard= chomp_board_after_eating_cookie(self,i,j)
newcookies = newboard.number_of_cookies()
damage = oldcookies - newcookies
M[i,j] = damage
return M
def eigen(self):
M = self.squared_matrix()
L = M.eigenvalues()
return [x for x in L if x.is_real()]
def damage_matrix(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
number = 0
M= self.damage_matrix()
for i in range(M_rows):
for j in range(M_columns):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
number = 0
M= self.damage_matrix()
for i in range(M_rows):
for j in range(M_columns):
number = number + M[i,j]
return number
def row_gcd(self):
return gcd([sum(x) for x in self.rows()])
def row_product(self):
if self.rows() == []:
return 0
return prod(self.rows())
def column_product(self):
if self.name() == "[]":
return 0
return prod(self.columns()) number = number + M[i,j]
return number
def row_gcd(self):
return gcd(self.rows())
def row_lcm(self):
return lcm(self.rows())
def laura_number_sum(self):
if self._rows == []:
return 0
if self.number_of_rows() == 1:
return 2*self._rows[0] - 2
row1_laura_number = 2*self._rows[0] - 2 + self._rows[1]
other_row_laura_number = 0
for i in range(1, self.number_of_rows() - 1):
other_row_laura_number += 3*self._rows[i] + self._rows[i+1] - 2
other_row_laura_number += 3*self._rows[-1] - 2
return row1_laura_number + other_row_laura_number
def damage_sum(self):
M_columns = self.number_of_columns()
M_rows = self.number_of_rows()
number = 0
M= self.damage_matrix()
for i in range(M_rows):
for j in range(M_columns):
number = number + M[i,j]
return number
def row_product(self):
if self.rows() == []:
return 0
return prod(self.rows())
def column_product(self):
if self.name() == "[]":
return 0
return prod(self.columns())
def column_gcd(self):
output = self.column_product()
for column in self.columns():
output = gcd(output,column)
return output
def column_lcm(self):
return lcm([sum(x) for x in self.columns()])
def row_lcm(self):
return lcm([sum(x) for x in self.rows()])
def trace_damage(self):
M = self.squared_damage_matrix()
return M.trace()
def average_damage(self):
damage_sum = self.damage_sum()
cookies = self.number_of_cookies()
average = damage_sum/cookies
return average
def rank_ratio(self):
rank = self.rows_of_different_length()
rows = self.number_of_rows()
return n(rank/rows)
def average_cookies_per_row(self):
count = 0
rows = self.number_of_rows()
for cookies in self.rows():
count = count + cookies
return n(count/rows)
def average_cookies_per_column(self):
count = 0
columns = self.number_of_columns()
for cookies in self.columns():
count = count + cookies
return n(count/columns)
def bevel(self):
total = 0
row_diff = 0
i=0
while i <= self.number_of_rows()-2:
if self.rows()[i] - self.rows()[i+1] == 0:
total = total + row_diff
else:
row_diff = self.rows()[i] - self.rows()[i+1]
total = total + row_diff
i=i+1
return total
def smallest_row_size(self):
return min(self.rows())
def smallest_column_size(self):
M = self.matrix()
return min(M.columns())
def cookies_inside(self):
cookies = self.number_of_cookies()
M = self.number_of_rows()
N = self.number_of_columns()
if M == 1 or N == 1:
inside = 0
else:
inside = cookies - (M+N-1)
return inside
def cookies_inside_ratio(self):
cookies = self.number_of_cookies()
inside = self.cookies_inside()
ratio = n(inside/cookies)
return ratio
def row_remainder(self):
M = self.number_of_rows()
cookies = self.number_of_cookies()
remainder = mod(cookies,M)
return remainder
def column_remainder(self):
N = self.number_of_columns()
cookies = self.number_of_cookies()
remainder = mod(cookies,N)
return remainder
def row_difference(board):
M = []
for x in range(len(board)):
if x < len(board)-1:
M.append(board[x]-board[x+1])
M.append(board[len(board)-1])
return M
def column_difference(board):
M = []
N = []
T = ChompBoard([5,4,2,1]).matrix().transpose()
for x in range(board[0]):
M.append(sum(T[x]))
return filter(lambda x: x != 0, row_difference(M))
def step_list(board):
A = row_difference(board)
B = column_difference(board)
C = []
for x in range(len(A)):
C.append(B[x])
C.append(A[x])
return C
def is_P_board(self):
if is_P_position(self):
return True
else:
return False
def is_N_board(self):
if is_N_position(self):
return True
else:
return False
def odd_cookies(self):
number = self.number_of_cookies()
if is_even(number):
return False
else:
return True
def even_cookies(self):
number = self.number_of_cookies()
if is_even(number):
return True
else:
return False
def is_square(self):
M = self.number_of_rows()
N = self.number_of_columns()
C = self.number_of_cookies()
if M != N:
return False
elif C != M*N:
return False
else:
return True
def is_rectangle(self):
M = self.number_of_rows()
N = self.number_of_columns()
C = self.number_of_cookies()
if C != M*N:
return False
else:
return True
def test_theorem1(self):
C = self.number_of_cookies()
col = self.number_of_columns()
if C >= 2*col - 1:
return True
else:
return False
def squareness_is_zero(self):
M = self.number_of_rows()
N = self.number_of_columns()
if M == N:
return True
else:
return False
def even_trace(self):
T = self.trace_square()
if is_even(T):
return True
else:
return False
def odd_trace(self):
T = self.trace_square()
if is_odd(T):
return True
else:
return False
def is_balanced_L(self):
M = self.number_of_rows()
N = self.number_of_columns()
C = self.number_of_cookies()
if M == N and C == M + N - 1:
return True
else:
return False
def is_unbalanced_L(self):
M = self.number_of_rows()
N = self.number_of_columns()
C = self.number_of_cookies()
if C > M+N-1:
return False
elif M == N:
return False
elif M == 1 or N == 1:
return False
else:
return True
def is_two_row_solution(self):
M = self.number_of_rows()
N = self.number_of_columns()
C = self.number_of_cookies()
if M != 2 and N != 2:
return False
elif C != (2*M)-1 and C != (2*N)-1:
return False
else:
return True
def rank_one_property(self):
R = self.rows_of_different_length()
if R > 1:
return False
else:
return True
def rank_non_one_property(self):
R = self.rows_of_different_length()
if R > 1:
return True
else:
return False
def test_theorem1(self):
C = self.number_of_cookies()
col = self.number_of_columns()
if C >= 2*col - 1:
return True
else:
return False
def reachable_balanced_L(self):
reachable = find_reachable_boards(self)
for board in reachable:
if board.balanced_L() == True:
return True
return False
def reachable_unbalanced_L(self):
reachable = find_reachable_boards(self)
for board in reachable:
if board.unbalanced_L() == True:
return True
return False
def reachable_two_row_solution(self):
reachable = find_reachable_boards(self)
for board in reachable:
if board.two_row_solution() == True:
return True
return False
def test_P_position(self):
if is_P_position(self)== True:
return True
else:
return False
def three_row_one_cookie(self):
M_rows = self.number_of_rows()
if M_rows == 3:
if self._rows[2]==1:
if self.rows[0] == 2 and self.rows[1]==2:
return True
elif self.rows[1] == 1 and self.rows[0]==3:
return True
else:
return False
else:
return False
else:
return False
def is_almost_L(self):
M_rows = self.number_of_rows()
M_col = self.number_of_columns()
cookies = self.number_of_cookies()
if abs(M_rows-M_col) != 1:
return False
elif cookies != M_rows + M_col:
return True
else:
return False
def test_prime_cookies(self):
def test_row_theorem(self):
M = self.number_of_rows()
cookies = self.number_of_cookies()
if cookies >= 2*M - 1:
return False
elif is_even(M_rows) and M_rows < M_col:
return True
elif is_even(M_col) and M_col < M_rows:
return True
else:
return False
def three_row_two_cookie(self):
M_rows = self.number_of_rows()
if M_rows == 3:
if self._rows[2]==2 and (self.rows[0]-self.rows[1])==2:
return True
else:
return False
else:
return False
def is_almost_L(self):
M_rows = self.number_of_rows()
M_col = self.number_of_columns()
cookies = self.number_of_cookies()
if abs(M_rows-M_col) != 1:
return False
elif cookies != M_rows + M_col:
return True
else:
return False
def test_prime_cookies(self):
N = self.number_of_columns()
cookies = self.number_of_cookies()
if M == 1 or N == 1:
return True
elif cookies-(M+N-1) < M+N-1:
return True
else:
return False
def cookies_divisible_by_rows(self):
M = self.number_of_rows()
cookies = self.number_of_cookies()
if mod(cookies,M) == 0:
return True
else:
return False
def cookies_divisible_by_columns(self):
N = self.number_of_columns()
cookies = self.number_of_cookies()
if mod(cookies,N) == 0:
return True
else:
return False
def test_row_theorem(self):
M = self.number_of_rows()
cookies = self.number_of_cookies()
if cookies >= 2*M - 1:
return False
elif is_even(M_rows) and M_rows < M_col:
return True
elif is_even(M_col) and M_col < M_rows:
return True
else:
return False
def test_Theorem2(self):
M_rows = self.number_of_rows()
M_col = self.number_of_columns()
cookies = self.number_of_cookies
if M_col == M_rows + 1 and cookies == M_rows + M_col:
return True
else:
return False
def test_prime_cookies(self):
cookies = self.number_of_cookies()
if is_prime(cookies):
return True
else:
False
def test_row_theorem(self):
M = self.number_of_rows()
cookies = self.number_of_cookies()
if cookies >= 2*M - 1:
return True
else:
return False
def composite_odd_cookies(self):
cookies = self.number_of_cookies()
if is_even(cookies):
return False
elif is_prime(cookies):
return False
else:
return True
def rows_greater_than_columns(self):
M = self.number_of_rows()
N = self.number_of_columns()
if M > N :
return True
else:
return False
def columns_greater_than_rows(self):
M = self.number_of_rows()
N = self.number_of_columns()
if M < N :
return True
else:
return False
def is_symmetric(self):
board = self.rows()
transpose = self.columns()
if board == transpose:
return True
else:
return False
def cookies_in_greater_than_cookies_out(self):
M = self.number_of_rows()
N = self.number_of_columns()
cookies = self.number_of_cookies()
if M == 1 or N == 1:
return False
elif cookies-(M+N-1) > M+N-1:
return True
else:
return False
def cookies_out_greater_than_cookies_in(self):
M = self.number_of_rows()
N = self.number_of_columns()
cookies = self.number_of_cookies()
if M == 1 or N == 1:
return True
elif cookies-(M+N-1) < M+N-1:
return True
else:
return False
def cookies_divisible_by_rows(self):
M = self.number_of_rows()
cookies = self.number_of_cookies()
if mod(cookies,M) == 0:
return True
else:
return False
def cookies_divisible_by_columns(self):
N = self.number_of_columns()
cookies = self.number_of_cookies()
if mod(cookies,N) == 0:
return True
else:
return False
def test_completes_self(board):
A = step_list(board)[0:(len(step_list(board))-1)]
B = step_list(board)[1:len(step_list(board))]
if A == A[::-1] or B == B[::-1]:
return True
else:
return False
def string_to_list(string):
L = []
for x in str(string[1:(len(string)-1):3]):
L.append(int(x))
return L
def chomp_board_after_eating_cookie(board,i,j):
board_rows = board.rows()
m = board.number_of_rows()
n = board.number_of_columns()
new = board.rows()
for k in range(i,m):
new[k] = min(board_rows[k],j)
return ChompBoard(new)
def find_reachable_boards(board):
reachable = []
if board.rows() == []:
return reachable
m = board.number_of_rows()
n = board.number_of_columns()
for i in range(m):
for j in range(n):
new = chomp_board_after_eating_cookie(board,i,j)
if new.rows() != board.rows():
if new.number_of_rows() >= 1:
reachable.append(new)
return reachable
def find_move(oldboard, newboard):
row = -1
column = -1
if oldboard.number_of_columns() != newboard.number_of_columns():
return (0, newboard.rows()[0])
elif oldboard.number_of_rows() != newboard.number_of_rows():
return (newboard.number_of_rows(), 0)
else:
old= oldboard.matrix()
newmatrix = newboard.matrix()
for row in range(oldboard.number_of_rows()):
for cookie in range(oldboard.rows()[row]):
if oldmatrix[row][cookie] != newmatrix[row][cookie]:
return (row, cookie)
try:
temp = load("position_values.sobj")
position_values = temp
except:
position_values = {str([]):"N"}
def is_N_position(B):
if B.name() in position_values:
if position_values[B.name()] == "N":
return True
else:
return False
else:
value = any(is_P_position(A) for A in find_reachable_boards(B))
if value == True:
position_values[B.name()] = "N"
return True
else:
position_values[B.name()] = "P"
return False
def is_P_position(B):
if B.name() in position_values:
if position_values[B.name()] == "P":
return True
else:
return False
else:
value = is_N_position(B)
if value == True:
position_values[B.name()] = "N"
return False
else:
position_values[B.name()] = "P"
return True
def find_reachable_P_positions(B):
reachable = find_reachable_boards(B)
reachable_P = []
for x in reachable:
if is_P_position(x):
reachable_P.append(x)
save(position_values, "position_values.sobj")
return reachable_P
def find_reachable_N_positions(B):
reachable = find_reachable_boards(B)
reachable_N = []
for x in reachable:
if not is_P_position(x):
reachable_N.append(x)
return reachable_N
def save_position_values():
output = open('known_positions.p', 'wb')
pickle.dump(position_values, output)
output.close()
def load_position_values():
global position_values
input = open('known_positions.p', 'rb')
position_values = pickle.load(input)
def print_position_values_formatted():
p_out = "P-Positions:\n"
n_out = "N-Positions:\n"
for k, v in position_values.iteritems():
if v == 'P':
p_out += "ChompBoard({}), ".format(k)
elif v == 'N':
n_out += "ChompBoard({}), ".format(k)
print p_out,'\n\n', n_out
def print_P_position_values_formatted():
p_out = "P-Positions:\n"
n_out = "N-Positions:\n"
for k, v in position_values.iteritems():
if v == 'P':
p_out += "ChompBoard({}), ".format(k)
elif v == 'N':
n_out += "ChompBoard({}), ".format(k)
print p_out
def print_N_position_values_formatted():
p_out = "P-Positions:\n"
n_out = "N-Positions:\n"
for k, v in position_values.iteritems():
if v == 'P':
p_out += "ChompBoard({}), ".format(k)
elif v == 'N':
n_out += "ChompBoard({}), ".format(k)
print n_out
import ast
def convert_board_name_to_board(name_of_board):
L = ast.literal_eval(name_of_board)
return ChompBoard(L)
Pexamples = [board_name for board_name in position_values if position_values[board_name]=="P"]
Nexamples = [board_name for board_name in position_values if position_values[board_name]=="N"]
try:
temp = load("Pcounterexamples.sobj")
Pcounterexamples = temp
except:
Pcounterexamples = ["[1]"]
try:
temp = load("Ncounterexamples.sobj")
Ncounterexamples = temp
except:
Ncounterexamples = ["[2]"]
def find_Pcounterexample(conj, row_limit, column_limit):
for s in Pcounterexamples:
board = convert_board_name_to_board(s)
try:
value = conj.evaluate(board)
if value == False:
print "{} is a counterexample to: {}".format(board.name(),conj)
return board
except:
print "error with evaluating: {} for {}".format(conj,board.name())
L = find_reachable_P_positions(ChompBoard([column_limit]*row_limit))
for board in L:
try:
value = conj.evaluate(board)
if value == False and board.name() not in Pcounterexamples:
Pcounterexamples.append(board.name())
print "{} is a counterexample to: {}".format(board.name(),conj)
return board
except:
print "error with evaluating: {} for {}".format(conj,board.name())
print "{}: No counterexamples found".format(conj)
def find_Ncounterexample(conj, row_limit, column_limit):
for s in Ncounterexamples:
board = convert_board_name_to_board(s)
try:
value = conj.evaluate(board)
if value == False:
print "{} is a counterexample to: {}".format(board.name(),conj)
return board
except:
print "error with evaluating: {} for {}".format(conj,board.name())
L = find_reachable_N_positions(ChompBoard([column_limit]*row_limit))
for board in L:
try:
value = conj.evaluate(board)
if value == False and board.name() not in Ncounterexamples:
Ncounterexamples.append(board.name())
print "{} is a counterexample to: {}".format(board.name(),conj)
return board
except:
print "error with evaluating: {} for {}".format(conj,board.name())
print "{}: No counterexamples found".format(conj)
def find_Pcounterexamples(conjs, row_limit, column_limit):
for conj in conjs:
find_Pcounterexample(conj, row_limit, column_limit)
save(Pcounterexamples, "Pcounterexamples.sobj")
def find_Ncounterexamples(conjs, row_limit, column_limit):
for conj in conjs:
find_Ncounterexample(conj, row_limit, column_limit)
save(Ncounterexamples, "Ncounterexamples.sobj")
def find_p_unique_conjs(conjs, row_limit, column_limit):
pconjs= []
for i in range(len(conjs)):
if find_Ncounterexample(conjs[i],row_limit,column_limit) != []:
pconjs.append(conjs[i])
return pconjs
ucla = ChompBoard([7,7,7,7])
Nspecial = ["[2]", "[10]", "[3,2,1]", "[4,2]", "[7,2]", "[7,7,7,7]", "[3,2,1,1]", "[3,3,3,3,3,3,3,3,3,3,2]", "[24,13,13,13,13,6]", "[28,25,15]", "[15,15,9,6]", "[2,2,2,2,2,2,2,2,2,2,2,2]"] + Ncounterexamples
Pspecial = ["[2,1]", "[1]", "[5,1,1,1,1]", "[3,2]", "[7,6]", "[100,45,45,45]", "[3,3,3,3,3,3,1,1,1,1,1]", "[24,13,7,7,7,6]", "[28,17,15]", "[15,13,9,6]", "[2,2,2,2,2,2,2,2,2,2,2,1]", "[11,11,10,9,8,8,5,5]"] + Pcounterexamples