69 lines
5.5 KiB
Python
69 lines
5.5 KiB
Python
import numpy as np
|
|
|
|
def solution(g):
|
|
grid = np.array(g)
|
|
height, width = grid.shape
|
|
|
|
prev_cases = {i:1 for i in generate_prev_cases(grid[:, 0])}
|
|
memo = {}
|
|
|
|
for column in range(width):
|
|
cases = {}
|
|
c = 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]
|
|
prev_cases = cases
|
|
return sum(prev_cases.values())
|
|
|
|
def generate_prev_cases(column):
|
|
if len(column) == 0:
|
|
yield 0
|
|
yield 1
|
|
else:
|
|
for v in generate_prev_cases(column[:-1]):
|
|
if column[len(column)-1] and v&1 == 1:
|
|
yield v<<1|0
|
|
else:
|
|
yield v<<1|0
|
|
yield v<<1|1
|
|
|
|
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
|
|
return single_one
|
|
|
|
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),
|
|
# to test time consumption, the answer is not correct
|
|
([[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)
|