class ParentError(Exception):
pass
def solve(puzzle, board):
def cleanup(name):
"board is passed by reference, so return it untouched."
if name in board:
del(board[name])
name,row_clue,length = puzzle[0]
puzzle_tail = puzzle[1:]
summary = cross_row(board, name)
ban = [] # holds tuples, (position, value_banned)
valid_children = (r for r in all_rle(row_clue, length) if valid(summary, r))
for row in valid_children:
if any(row[i] == v for i,v in ban):
if len(set(zip(*ban)[0])) != len(zip(*ban)[0]):
# 1 and 0 both banned in same position, big problem
cleanup(board, name)
raise ParentError
continue
board[name] = row
if not puzzle_tail: # out of clues, puzzle solved, print it
print_board(board)
else:
try:
solve(puzzle_tail, board)
except ParentError:
if name[0] == puzzle_tail[0][1][0]:
# parallel rows do not intersect, handle elsewhere
cleanup(board, name)
raise ParentError
else:
err_index = index[puzzle_tail[0][1]]
ban.append( (err_index, row[err_index]) )
# all clues tested, go back up
cleanup(name)
def print_board(board):
rows = sorted((index[k], board[k]) for k in board if k[0] == 'R')
for pos,data in rows:
print ''.join(('.','#')[int(char,10)] for char in data)
print