class ProblemTest(unittest.TestCase): """ Tests for l1sudoku Problem class """ def setUp(self): """ Instantiate one Problem at random from TOP95 """ self.sudoku = Problem(random_puzzle()) self.N = 9 def test_puzzle(self): """ Test we create a Problem correctly from a string """ print(unicode(self.sudoku)) self.assertEqual(self.N, self.sudoku.N) self.assertTrue(len(unicode(self.sudoku)) > self.sudoku.N**2) def test_box_size(self): """ Test we get correct boxsize if N is square and large enough. """ self.assertEqual(3, Problem("." * 81, N=9).get_box_size()) self.assertEqual(2, Problem("." * 16, N=4).get_box_size()) self.assertEqual(0, Problem("." * 4, N=2).get_box_size()) self.assertEqual(0, Problem("." * 100, N=10).get_box_size()) def test_nentries(self): """ Check the Problem correctly counts the number of clue entries. """ sudoku = Problem('1' + '.' * (self.N**2 - 1), N=self.N) self.assertEqual(1, sudoku.num_entries()) rp = random_puzzle().strip() nentries_rp = len([e for e in rp if e != '.']) sudoku = Problem(rp) self.assertEqual(nentries_rp, sudoku.num_entries()) def test_matrix(self): """ Test the problem matrix generated by the Problem """ m = self.sudoku.matrix() self.assertTrue(isinstance(m, matrix)) nentries = len([e for e in self.sudoku.entries if e]) N = self.sudoku.N self.assertEqual((4 * N**2 + nentries, N**3), m.size) def test_to_indicator(self): """ Test the problem matrix generated by the Problem """ N = self.N num = randint(1, N) pos = randint(0, N**2 - 1) sudoku = make_problem(chr(ord('0') + num), pos) iv = sudoku.to_indicator_vector() self.assertTrue(isinstance(iv, matrix)) self.assertEqual((N**3, 1), iv.size) self.assertEqual(1, sum(iv)) self.assertEqual(N * pos + num - 1, list(iv).index(1)) s2 = Problem.from_indicator_vector(iv) self.assertEqual(unicode(sudoku), unicode(s2)) def test_all_cells_constraint(self): """ Check the matrix constraint that ensures all cells are filled. """ # - Construct a Problem with all cells filled # - Get the all_cells matrix # - Multiply it with the indicator vector # - check the result is all ones # - blank a cell, repeat # - check the result is not all ones N = self.N sudoku = Problem("1" * N**2) v = sudoku.get_result(all_cells=True) self.assertOnes(v) v = self.sudoku.get_result(all_cells=True) self.assertNotOnes(v) def test_row_digits_constraint(self): """ Check the matrix constraint that ensures each row contains all digits """ # - Construct a Problem with all cells filled # - Get the all_cells matrix # - Multiply it with the indicator vector # - check the result is all ones # - blank a cell, repeat # - check the result is not all ones N = 9 sudoku = Problem("123456789" * N) v = sudoku.get_result(row_digits=True) self.assertOnes(v) v = self.sudoku.get_result(row_digits=True) self.assertNotOnes(v) def test_col_digits_constraint(self): """ Check the matrix constraint that ensures each row contains all digits """ # - Construct a Problem with all cells filled # - Get the all_cells matrix # - Multiply it with the indicator vector # - check the result is all ones # - blank a cell, repeat # - check the result is not all ones N = 9 entries = reduce( operator.__add__, [list(itertools.repeat(i, N)) for i in range(1, N + 1)]) sudoku = Problem(entries) v = sudoku.get_result(col_digits=True) self.assertOnes(v) v = self.sudoku.get_result(col_digits=True) self.assertNotOnes(v) def test_box_digits_constraint(self): """ Check the matrix constraint that ensures each box contains all digits """ # - Construct a Problem with all cells filled # - Get the all_cells matrix # - Multiply it with the indicator vector # - check the result is all ones # - blank a cell, repeat # - check the result is not all ones N = 9 sudoku = Problem("123123123" "456456456" "789789789" "123123123" "456456456" "789789789" "123123123" "456456456" "789789789") v = sudoku.get_result(box_digits=True) self.assertOnes(v) v = self.sudoku.get_result(box_digits=True) self.assertNotOnes(v) def test_clues_constraint(self): """ Check the matrix constraint that ensures the answer is consistent with the clues. """ N = 9 num = randint(1, N) pos = randint(0, N**2 - 1) sudoku = make_problem(chr(ord('0') + num), pos) v = sudoku.get_result(clues=True) self.assertOnes(v) def assertOnes(self, vector): """ Assert the vector consists entirely of ones. """ self.assertTrue(all_ones(vector)) def assertNotOnes(self, vector): """ Assert the vector does not consist entirely of ones. """ self.assertFalse(all([e == 1 for e in vector])) def test_solve(self): """ Test solving the Problem. """ # Easy test self.sudoku = Problem( '.81.749....4.193.7379.85.14..7831...238456179..69274..843562791762198543..5743862' ) answer = self.sudoku.solve() checkAnswer = Problem( '681374925524619387379285614497831256238456179156927438843562791762198543915743862' ) self.assertEqual(unicode(checkAnswer), unicode(answer)) answer = self.sudoku.solve() checkAnswer = Problem( '681374925524619387379285614497831256238456179156927438843562791762198543915743862' ) self.assertEqual(unicode(checkAnswer), unicode(answer)) def test_solve_plainl1(self): """ Test the solve_min function. """ M = matrix([1, 1, 1, 1, 0, 1], (2, 3), 'd') b = ones_v(2) x = solve_plain_l1(M, b) self.assertEqual(tuple(b), tuple(M * x))
class ProblemTest(unittest.TestCase): """ Tests for l1sudoku Problem class """ def setUp(self): """ Instantiate one Problem at random from TOP95 """ self.sudoku = Problem(random_puzzle()) self.N = 9 def test_puzzle(self): """ Test we create a Problem correctly from a string """ print unicode(self.sudoku) self.assertEqual(self.N, self.sudoku.N) self.assertTrue(len(unicode(self.sudoku)) > self.sudoku.N **2) def test_box_size(self): """ Test we get correct boxsize if N is square and large enough. """ self.assertEqual(3, Problem("."*81,N=9).get_box_size()) self.assertEqual(2, Problem("."*16,N=4).get_box_size()) self.assertEqual(0, Problem("."*4,N=2).get_box_size()) self.assertEqual(0, Problem("."*100,N=10).get_box_size()) def test_nentries(self): """ Check the Problem correctly counts the number of clue entries. """ sudoku = Problem('1' + '.'*(self.N **2 -1), N=self.N) self.assertEqual(1, sudoku.num_entries()) rp = random_puzzle().strip() nentries_rp = len([e for e in rp if e != '.']) sudoku = Problem(rp) self.assertEqual(nentries_rp, sudoku.num_entries()) def test_matrix(self): """ Test the problem matrix generated by the Problem """ m = self.sudoku.matrix() self.assertTrue(isinstance(m ,matrix )) nentries = len([e for e in self.sudoku.entries if e]) N = self.sudoku.N self.assertEqual((4 * N**2 + nentries, N**3), m.size) def test_to_indicator(self): """ Test the problem matrix generated by the Problem """ N = self.N num = randint(1,N) pos = randint(0,N**2-1) sudoku = make_problem(chr(ord('0') + num), pos) iv = sudoku.to_indicator_vector() self.assertTrue(isinstance(iv ,matrix )) self.assertEqual((N**3,1), iv.size) self.assertEqual(1, sum(iv)) self.assertEqual(N*pos+num-1, list(iv).index(1)) s2 = Problem.from_indicator_vector(iv) self.assertEqual(unicode(sudoku),unicode(s2)) def test_all_cells_constraint(self): """ Check the matrix constraint that ensures all cells are filled. """ # - Construct a Problem with all cells filled # - Get the all_cells matrix # - Multiply it with the indicator vector # - check the result is all ones # - blank a cell, repeat # - check the result is not all ones N = self.N sudoku = Problem("1"*N**2) v = sudoku.get_result(all_cells=True) self.assertOnes(v) v = self.sudoku.get_result(all_cells=True) self.assertNotOnes(v) def test_row_digits_constraint(self): """ Check the matrix constraint that ensures each row contains all digits """ # - Construct a Problem with all cells filled # - Get the all_cells matrix # - Multiply it with the indicator vector # - check the result is all ones # - blank a cell, repeat # - check the result is not all ones N = 9 sudoku = Problem("123456789"*N) v = sudoku.get_result(row_digits=True) self.assertOnes(v) v = self.sudoku.get_result(row_digits=True) self.assertNotOnes(v) def test_col_digits_constraint(self): """ Check the matrix constraint that ensures each row contains all digits """ # - Construct a Problem with all cells filled # - Get the all_cells matrix # - Multiply it with the indicator vector # - check the result is all ones # - blank a cell, repeat # - check the result is not all ones N = 9 entries = reduce(operator.__add__, [list(itertools.repeat(i,N)) for i in range(1,N+1)]) sudoku = Problem(entries) v = sudoku.get_result(col_digits=True) self.assertOnes(v) v = self.sudoku.get_result(col_digits=True) self.assertNotOnes(v) def test_box_digits_constraint(self): """ Check the matrix constraint that ensures each box contains all digits """ # - Construct a Problem with all cells filled # - Get the all_cells matrix # - Multiply it with the indicator vector # - check the result is all ones # - blank a cell, repeat # - check the result is not all ones N = 9 sudoku = Problem("123123123" "456456456" "789789789" "123123123" "456456456" "789789789" "123123123" "456456456" "789789789") v = sudoku.get_result(box_digits=True) self.assertOnes(v) v = self.sudoku.get_result(box_digits=True) self.assertNotOnes(v) def test_clues_constraint(self): """ Check the matrix constraint that ensures the answer is consistent with the clues. """ N = 9 num = randint(1,N) pos = randint(0,N**2-1) sudoku = make_problem(chr(ord('0') + num), pos) v = sudoku.get_result(clues=True) self.assertOnes(v) def assertOnes(self, vector): """ Assert the vector consists entirely of ones. """ self.assertTrue(all_ones(vector)) def assertNotOnes(self, vector): """ Assert the vector does not consist entirely of ones. """ self.assertFalse(all([e==1 for e in vector])) def test_solve(self): """ Test solving the Problem. """ # Easy test self.sudoku = Problem('.81.749....4.193.7379.85.14..7831...238456179..69274..843562791762198543..5743862') answer = self.sudoku.solve() checkAnswer = Problem('681374925524619387379285614497831256238456179156927438843562791762198543915743862') self.assertEqual(unicode(checkAnswer), unicode(answer) ) answer = self.sudoku.solve() checkAnswer = Problem('681374925524619387379285614497831256238456179156927438843562791762198543915743862') self.assertEqual(unicode(checkAnswer), unicode(answer) ) def test_solve_plainl1(self): """ Test the solve_min function. """ M = matrix([1,1,1,1,0,1],(2,3),'d') b = ones_v(2) x = solve_plain_l1(M, b) self.assertEqual(tuple(b), tuple(M*x))