Nonograms

Initial, probably buggy, load of a literate python program.

Comments are moderated. It may take a few minutes before your comment appears.
Markdown is supported in your comments.

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
Name:
Mail: (not shown)

Please type this: