def test_solve_4x3(self):
        # from http://regexcrossword.com/playerpuzzles/edfb2756-41e9-4aca-a706-abe640d8c71e
        cw = Crossword(4, 3)

        cw.add_regex(1, 'A', '[MELT]+.[JERK]+')
        cw.add_regex(2, 'A', '[AND]+.K')
        cw.add_regex(3, 'A', '[HEY!!]+')

        cw.add_regex(1, 'D', '[NOT][RAT]E')
        cw.add_regex(2, 'D', 'H[DRO][^HE!!]')
        cw.add_regex(3, 'D', '[THEN]E!')
        cw.add_regex(4, 'D', '[JUMP].!')

        # the answer includes an !, so this will raise an error
        self.assertRaises(UnsolvableError, cw.solve)  # what's the answer?

        cw.add_to_possibility('!')
        self.assertEqual(cw.solve(), 'THEJADEKEY!!')
    def test_solve_4x3(self):
        # from http://regexcrossword.com/playerpuzzles/edfb2756-41e9-4aca-a706-abe640d8c71e
        cw = Crossword(4, 3)

        cw.add_regex(1, 'A', '[MELT]+.[JERK]+')
        cw.add_regex(2, 'A', '[AND]+.K')
        cw.add_regex(3, 'A', '[HEY!!]+')

        cw.add_regex(1, 'D', '[NOT][RAT]E')
        cw.add_regex(2, 'D', 'H[DRO][^HE!!]')
        cw.add_regex(3, 'D', '[THEN]E!')
        cw.add_regex(4, 'D', '[JUMP].!')

        # the answer includes an !, so this will raise an error
        self.assertRaises(UnsolvableError, cw.solve)  # what's the answer?

        cw.add_to_possibility('!')
        self.assertEqual(cw.solve(), 'THEJADEKEY!!')
    def test_solve_3x3_with_special_chars(self):
        # http://regexcrossword.com/challenges/volapuk/puzzles/2
        cw = Crossword(3, 3)
        cw.add_to_possibility('.\\')
        cw.add_regex(1, 'A', r'(Y|\d|M)+')
        cw.add_regex(1, 'A', r'[^IB][0-3]Y')
        cw.add_regex(2, 'A', r'(.H|P|.P)+')
        cw.add_regex(2, 'A', r'^(P|Y)*(PA|\.H$)')
        cw.add_regex(3, 'A', r'[\dIP\s].+')
        cw.add_regex(3, 'A', r'[PA\\d\d]+')

        cw.add_regex(1, 'D', r'M[\DIP]*')
        cw.add_regex(1, 'D', r'(M|A|P)+')
        cw.add_regex(2, 'D', r'(\\d|\d.)[\\\/B]')
        cw.add_regex(2, 'D', r'[^2O13]\.\\*(A|P)?')
        cw.add_regex(3, 'D', r'(Y$|YH|\d$)+')
        cw.add_regex(3, 'D', r'[HOW2Y]+')

        self.assertEqual(cw.solve(), 'M0YP.HP\\2')
    def test_solve_3x3_with_special_chars(self):
        # http://regexcrossword.com/challenges/volapuk/puzzles/2
        cw = Crossword(3, 3)
        cw.add_to_possibility('.\\')
        cw.add_regex(1, 'A', r'(Y|\d|M)+')
        cw.add_regex(1, 'A', r'[^IB][0-3]Y')
        cw.add_regex(2, 'A', r'(.H|P|.P)+')
        cw.add_regex(2, 'A', r'^(P|Y)*(PA|\.H$)')
        cw.add_regex(3, 'A', r'[\dIP\s].+')
        cw.add_regex(3, 'A', r'[PA\\d\d]+')

        cw.add_regex(1, 'D', r'M[\DIP]*')
        cw.add_regex(1, 'D', r'(M|A|P)+')
        cw.add_regex(2, 'D', r'(\\d|\d.)[\\\/B]')
        cw.add_regex(2, 'D', r'[^2O13]\.\\*(A|P)?')
        cw.add_regex(3, 'D', r'(Y$|YH|\d$)+')
        cw.add_regex(3, 'D', r'[HOW2Y]+')

        self.assertEqual(cw.solve(), 'M0YP.HP\\2')