from collections import defaultdict
import itertools
N = 3
def solve(grid, x, y, nums, total=None):
if not nums:
return 1
if x == N-1:
return solve(grid, 0, y+1, nums, total)
output = 0
if x == y == 0:
for a,b,c,d in itertools.permutations(nums, 4):
# print(a,b,c,d)
grid[0,0], grid[0,1], grid[1,0], grid[1,1] = a, b, c, d
nums -= {a,b,c,d}
output += solve(grid, x+1, y, nums, a+b+c+d)
nums |= {a,b,c,d}
del grid[0,0], grid[0,1], grid[1,0], grid[1,1]
elif y == 0:
for a,b in itertools.combinations(nums, 2):
if grid[y,x] + grid[y+1,x] + a + b == total:
grid[y,x+1], grid[y+1,x+1] = a, b
nums -= {a, b}
output += solve(grid, x+1, y, nums, total)
grid[y,x+1], grid[y+1,x+1] = b, a
output += solve(grid, x+1, y, nums, total)
nums |= {a, b}
del grid[y,x+1], grid[y+1,x+1]
elif x == 0:
for a,b in itertools.combinations(nums, 2):
if grid[y,x] + grid[y,x+1] + a + b == total:
grid[y+1,x], grid[y+1,x+1] = a, b
nums -= {a, b}
output += solve(grid, x+1, y, nums, total)
grid[y+1,x], grid[y+1,x+1] = b, a
output += solve(grid, x+1, y, nums, total)
nums |= {a, b}
del grid[y+1,x], grid[y+1,x+1]
else:
a = total - (grid[y,x] + grid[y,x+1] + grid[y+1,x])
if a in nums:
grid[y+1,x+1] = a
nums -= {a}
output += solve(grid, x+1, y, nums, total)
nums |= {a}
del grid[y+1,x+1]
return output
print(solve({}, 0, 0, set(range(N*N))))
ZnJvbSBjb2xsZWN0aW9ucyBpbXBvcnQgZGVmYXVsdGRpY3QKaW1wb3J0IGl0ZXJ0b29scwoKTiA9IDMKCmRlZiBzb2x2ZShncmlkLCB4LCB5LCBudW1zLCB0b3RhbD1Ob25lKToKICAgIGlmIG5vdCBudW1zOgogICAgICAgIHJldHVybiAxCgogICAgaWYgeCA9PSBOLTE6CiAgICAgICAgcmV0dXJuIHNvbHZlKGdyaWQsIDAsIHkrMSwgbnVtcywgdG90YWwpCgogICAgb3V0cHV0ID0gMAogICAgCiAgICBpZiB4ID09IHkgPT0gMDoKICAgICAgICBmb3IgYSxiLGMsZCBpbiBpdGVydG9vbHMucGVybXV0YXRpb25zKG51bXMsIDQpOgogICAgICAgICAgICAjIHByaW50KGEsYixjLGQpCiAgICAgICAgICAgIGdyaWRbMCwwXSwgZ3JpZFswLDFdLCBncmlkWzEsMF0sIGdyaWRbMSwxXSA9IGEsIGIsIGMsIGQKICAgICAgICAgICAgbnVtcyAtPSB7YSxiLGMsZH0KCiAgICAgICAgICAgIG91dHB1dCArPSBzb2x2ZShncmlkLCB4KzEsIHksIG51bXMsIGErYitjK2QpCgogICAgICAgICAgICBudW1zIHw9IHthLGIsYyxkfQogICAgICAgICAgICBkZWwgZ3JpZFswLDBdLCBncmlkWzAsMV0sIGdyaWRbMSwwXSwgZ3JpZFsxLDFdCgogICAgZWxpZiB5ID09IDA6CiAgICAgICAgZm9yIGEsYiBpbiBpdGVydG9vbHMuY29tYmluYXRpb25zKG51bXMsIDIpOgogICAgICAgICAgICBpZiBncmlkW3kseF0gKyBncmlkW3krMSx4XSArIGEgKyBiID09IHRvdGFsOgogICAgICAgICAgICAgICAgZ3JpZFt5LHgrMV0sIGdyaWRbeSsxLHgrMV0gPSBhLCBiCiAgICAgICAgICAgICAgICBudW1zIC09IHthLCBifQogICAgICAgICAgICAgICAgb3V0cHV0ICs9IHNvbHZlKGdyaWQsIHgrMSwgeSwgbnVtcywgdG90YWwpCgogICAgICAgICAgICAgICAgZ3JpZFt5LHgrMV0sIGdyaWRbeSsxLHgrMV0gPSBiLCBhCiAgICAgICAgICAgICAgICBvdXRwdXQgKz0gc29sdmUoZ3JpZCwgeCsxLCB5LCBudW1zLCB0b3RhbCkKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgbnVtcyB8PSB7YSwgYn0KICAgICAgICAgICAgICAgIGRlbCBncmlkW3kseCsxXSwgZ3JpZFt5KzEseCsxXQoKICAgIGVsaWYgeCA9PSAwOgogICAgICAgIGZvciBhLGIgaW4gaXRlcnRvb2xzLmNvbWJpbmF0aW9ucyhudW1zLCAyKToKICAgICAgICAgICAgaWYgZ3JpZFt5LHhdICsgZ3JpZFt5LHgrMV0gKyBhICsgYiA9PSB0b3RhbDoKICAgICAgICAgICAgICAgIGdyaWRbeSsxLHhdLCBncmlkW3krMSx4KzFdID0gYSwgYgogICAgICAgICAgICAgICAgbnVtcyAtPSB7YSwgYn0KCiAgICAgICAgICAgICAgICBvdXRwdXQgKz0gc29sdmUoZ3JpZCwgeCsxLCB5LCBudW1zLCB0b3RhbCkKCiAgICAgICAgICAgICAgICBncmlkW3krMSx4XSwgZ3JpZFt5KzEseCsxXSA9IGIsIGEKICAgICAgICAgICAgICAgIG91dHB1dCArPSBzb2x2ZShncmlkLCB4KzEsIHksIG51bXMsIHRvdGFsKQoKICAgICAgICAgICAgICAgIG51bXMgfD0ge2EsIGJ9CiAgICAgICAgICAgICAgICBkZWwgZ3JpZFt5KzEseF0sIGdyaWRbeSsxLHgrMV0KCiAgICBlbHNlOgogICAgICAgIGEgPSB0b3RhbCAtIChncmlkW3kseF0gKyBncmlkW3kseCsxXSArIGdyaWRbeSsxLHhdKQoKICAgICAgICBpZiBhIGluIG51bXM6CiAgICAgICAgICAgIGdyaWRbeSsxLHgrMV0gPSBhCiAgICAgICAgICAgIG51bXMgLT0ge2F9CiAgICAgICAgICAgIAogICAgICAgICAgICBvdXRwdXQgKz0gc29sdmUoZ3JpZCwgeCsxLCB5LCBudW1zLCB0b3RhbCkKCiAgICAgICAgICAgIG51bXMgfD0ge2F9CiAgICAgICAgICAgIGRlbCBncmlkW3krMSx4KzFdCgogICAgcmV0dXJuIG91dHB1dAoKcHJpbnQoc29sdmUoe30sIDAsIDAsIHNldChyYW5nZShOKk4pKSkp