WHITE = 1 BLACK = 2 UNKNOWN = WHITE|BLACK def solve_line(hint, line): line = line + [WHITE] # make our life easier n = len(line) m = len(hint) result = [0]*n memo = {} # memoization table def f(i,j): """ Try to see whether line[:i+1] can accomodate hint[:j+1] such that line[i] is white. """ if i == -1: return j == -1 if line[i] == BLACK: # must end in WHITE return False if (i,j) in memo: return memo[i,j] # can we just add one WHITE? opt1 = f(i-1, j) # can we fit the last BLACK hint in the end of line[:i] and the following WHITE at line[i-hint[j]-1]? opt2 = j>=0 and i>=hint[j] \ and WHITE not in line[i-hint[j]:i] \ and f(i-1-hint[j], j-1) if opt1: result[i] |= WHITE if opt2: result[i] |= WHITE for k in range(i-hint[j],i): result[k] |= BLACK memo[i,j] = answer = opt1 or opt2 return answer assert f(n-1,m-1) return result[:-1] # drop the surplus WHITE