Enable Javascript in your browser and then refresh this page, for a much enhanced experience.
Second solution in Speedy category for Magic Domino by terryyin
# migrated from python 2.7
def magic_domino(size, number):
completed = [[None for _ in range(size)] for _ in range(size)]
def check_(sz, su):
return su == number if sz==size else (number>=su>=number - 6 * (size - sz))
def fit(x, y):
if not check_(x+1, sum(completed[m][y] for m in range(x+1))): return False
if not check_(x+1, sum(completed[m][y+1] for m in range(x+1))): return False
return all(check_(len(diag), sum(diag)) for diag in (
[completed[m][m] for m in range(x+1)if completed[m][m] is not None],
[completed[m][-1-m] for m in range(x+1) if completed[m][-1-m] is not None]))
def place(tiles):
if completed[-1][-1] is not None: return True
x, y = divmod((28 - len(tiles))*2, size)
for t in tiles:
completed[x][y:y+2] = t
if check_(y+2, sum(completed[x][:y+2])):
ts = tiles-{t}
if fit(x, y) and place(ts): return True
completed[x][y:y+2] = t[::-1]
if fit(x, y) and place(ts): return True
completed[x][y:y+2] = None, None
place(set((x, y) for x in range(7) for y in range(x,7)))
return list(zip(*completed))
if __name__ == '__main__':
#These "asserts" using only for self-checking and not necessary for auto-testing
import itertools
def check_data(size, number, user_result):
# check types
check_container_type = lambda o: any([isinstance(o, t) for t in (list, tuple)])
check_cell_type = lambda i: isinstance(i, int)
if not (check_container_type(user_result) and
all(map(check_container_type, user_result)) and
all([all(map(check_cell_type, row)) for row in user_result])):
raise Exception("You should return a list/tuple of lists/tuples with integers.")
# check sizes
check_size = lambda o: len(o) == size
if not (check_size(user_result) and all(map(check_size, user_result))):
raise Exception("Wrong size of answer.")
# check is it a possible numbers (from 0 to 6 inclusive)
if not all([0 <= x <= 6 for x in itertools.chain.from_iterable(user_result)]):
raise Exception("Wrong matrix integers (can't be domino tiles)")
# check is it a magic square
seq_sum_check = lambda seq: sum(seq) == number
diagonals_indexes = list(zip(*[((i, i), (i, size - i - 1)) for i in range(size)]))
values_from_indexes = lambda inds: itertools.starmap(lambda x, y: user_result[y][x], inds)
if not (all(map(seq_sum_check, user_result)) and # rows
all(map(seq_sum_check, list(zip(*user_result)))) and # columns
all(map(seq_sum_check, list(map(values_from_indexes, diagonals_indexes))))): # diagonals
raise Exception("It's not a magic square.")
# check is it domino square
tiles = set()
for x, y in itertools.product(list(range(size)), list(range(0, size, 2))):
tile = tuple(sorted((user_result[y][x], user_result[y + 1][x])))
if tile in tiles:
raise Exception("It's not a domino magic square.")
tiles.add(tile)
check_data(4, 5, magic_domino(4, 5))
Aug. 13, 2014