Python 3.12, 10.33 s unofficial time
Python port of @Ander Kaseorg's Rust code.
import sys
import time
ROWS = 6
COLS = 6
def is_sorted_by_key(arr):
for i in range(1, ROWS):
prev_sum = sum(arr[i - 1])
curr_sum = sum(arr[i])
if curr_sum < prev_sum or (curr_sum == prev_sum and arr[i] < arr[i - 1]):
return False
return True
def transpose(m):
return [list(row) for row in zip(*m)]
def found_permutations(m, row_sums, i, permuted, found):
if i == ROWS:
if permuted:
mt = transpose(m)
mt.sort()
mtt = transpose(mt)
if is_sorted_by_key(mtt):
mtt_tuple = tuple(tuple(row) for row in mtt)
found.add(mtt_tuple)
else:
found_permutations(m, row_sums, i + 1, permuted, found)
for i1 in range(i + 1, ROWS):
if row_sums[i1] != row_sums[i]:
break
if m[i1] != m[i]:
m[i], m[i1] = m[i1], m[i]
found_permutations(m, row_sums, i + 1, True, found)
m[i], m[i1] = m[i1], m[i]
def search(m, i, j, row_sum, min_row_sum, equal_row, equal_cols, found, stdout, cnt):
if row_sum + (COLS - j) < min_row_sum:
return
if j == COLS:
i += 1
if i == ROWS:
m_tuple = tuple(tuple(row) for row in m)
if m_tuple not in found:
row_sums = [sum(row) for row in m]
found_permutations(m, row_sums, 0, False, found)
for row in m:
stdout.write(''.join('1' if cell else '0' for cell in row) + ' ')
stdout.write('\n')
cnt[0] += 1
return
else:
j = 0
min_row_sum = row_sum
row_sum = 0
equal_row = True
if i == 0 and j == 0:
m[i][j] = False
equal_cols_prev_j = equal_cols[j]
equal_cols[j] = False
search(m, i, j + 1, row_sum, min_row_sum, False, equal_cols, found, stdout, cnt)
equal_cols[j] = equal_cols_prev_j
m[i][j] = True
equal_cols_prev_j = equal_cols[j]
equal_cols[j] = False
search(m, i, j + 1, row_sum + 1, min_row_sum, False, equal_cols, found, stdout, cnt)
equal_cols[j] = equal_cols_prev_j
elif i == 0:
equal_col = equal_cols[j]
if not equal_col or not m[i][j - 1]:
m[i][j] = False
prev_equal_cols_j = equal_cols[j]
equal_cols[j] = equal_col and not m[i][j - 1]
search(m, i, j + 1, row_sum, min_row_sum, False, equal_cols, found, stdout, cnt)
equal_cols[j] = prev_equal_cols_j
m[i][j] = True
prev_equal_cols_j = equal_cols[j]
equal_cols[j] = equal_col and m[i][j - 1]
search(m, i, j + 1, row_sum + 1, min_row_sum, False, equal_cols, found, stdout, cnt)
equal_cols[j] = prev_equal_cols_j
elif j == 0:
m[i][j] = False
prev_equal_cols_j = equal_cols[j]
equal_cols[j] = False
m_i1_j = m[i - 1][j]
search(m, i, j + 1, row_sum, min_row_sum + int(equal_row and m_i1_j), equal_row and not m_i1_j, equal_cols, found, stdout, cnt)
equal_cols[j] = prev_equal_cols_j
m[i][j] = True
prev_equal_cols_j = equal_cols[j]
equal_cols[j] = False
m_i1_j = m[i - 1][j]
search(m, i, j + 1, row_sum + 1, min_row_sum, equal_row and m_i1_j, equal_cols, found, stdout, cnt)
equal_cols[j] = prev_equal_cols_j
else:
equal_col = equal_cols[j]
m_i1_j = m[i - 1][j]
if not equal_col or not m[i][j - 1]:
m[i][j] = False
prev_equal_cols_j = equal_cols[j]
equal_cols[j] = equal_col and not m[i][j - 1]
search(m, i, j + 1, row_sum, min_row_sum + int(equal_row and m_i1_j), equal_row and not m_i1_j, equal_cols, found, stdout, cnt)
equal_cols[j] = prev_equal_cols_j
m[i][j] = True
prev_equal_cols_j = equal_cols[j]
equal_cols[j] = equal_col and m[i][j - 1]
search(m, i, j + 1, row_sum + 1, min_row_sum, equal_row and m_i1_j, equal_cols, found, stdout, cnt)
equal_cols[j] = prev_equal_cols_j
def main():
equal_cols = [True] * COLS
equal_cols[0] = False
cnt = [0]
m = [[False] * COLS for _ in range(ROWS)]
found = set()
start = time.time()
stdout = sys.stdout
search(m, 0, 0, 0, 0, False, equal_cols, found, stdout, cnt)
duration = time.time() - start
print(f"Total count: {cnt[0]}")
print(f"Execution time: {duration} seconds")
if __name__ == '__main__':
main()
print(precomputed_answer)
). “Largest input within a fixed time” is better. \$\endgroup\$