import numpy as np def solution(g): #print_grid(g) grid = np.array(g) #print grid height, width = grid.shape #print height, width memo = {} prev_cases = {i:1 for i in range(2**(height+1))} #for i in range(2**(height+1)): # prev_cases[i] = 1 # memo[i] = {j:calculate_c_column(i, j, height) for j in range(2**(height+1))} #print memo #print prev_cases for column in range(width): cases = {} c = list_to_int(grid[:,column]) #print grid[:,column], list_to_int(grid[:,column]) for i in prev_cases.keys(): if not i in memo: memo[i] = {} if not c in memo[i]: memo[i][c] = [j for j in range(2**(height+1)) if calculate_c_column(i, j, height) == c] for j in memo[i][c]: if not j in cases: cases[j] = 0 if i in prev_cases: cases[j] += prev_cases[i] #print cases prev_cases = cases return sum(prev_cases.values()) def print_grid(g): for row in g: line = "" for elem in row: if elem: line+="O" else: line+="." print line def calculate_c_column(i, j, length): mask = 2**length-1 multiple_ones = ((i&j)|((i&j)>>1)) & mask odd_ones = ((i^j)^((i^j)>>1)) & mask single_one = (~multiple_ones & odd_ones) & mask #print ' '.join(('{:0'+str(length)+'b}').format(k) for k in [i, j]), ' '.join(('{:0'+str(length-1)+'b}').format(k) for k in [multiple_ones, odd_ones, single_one]) return single_one #l=3 #memo = {} #for i in range(2**(l-1)): # memo[i] = 0 #for i in range(2**l): # for j in range(2**l): # t = calculate_c_column(i, j, l) # memo[t] += 1 #print memo #exit(0) def list_to_int(l): value = 0 for v in l: value |= v value <<= 1 return value >> 1 tests = [ ([[True, True, False, True, False, True, False, True, True, False], [True, True, False, False, False, False, True, True, True, False], [True, True, False, False, False, False, False, False, False, True], [False, True, False, False, False, False, True, True, False, False]], 11567), ([[True, False, True], [False, True, False], [True, False, True]], 4), ([[True, False, True, False, False, True, True, True], [True, False, True, False, False, False, True, False], [True, True, True, False, False, False, True, False], [True, False, True, False, False, False, True, False], [True, False, True, False, False, True, True, True]] ,254), ([[True]], 4), ([[False]], 12), ([[True, True]], 6), ([[True, False]], 10), ([[False, True]], 10), ([[False, False]], 38), #([[True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False], [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False], [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False], [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False], [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False], [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False], [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False], [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False], [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False]], 1), ] for (i, o) in tests: result = solution(i) print(i, result == o, result, o)