backtrack.py

This commit is contained in:
Timo Schmidt 2023-03-26 05:50:21 +02:00
parent c4e3ab0672
commit 0a79846a4f
1 changed files with 36 additions and 21 deletions

View File

@ -7,6 +7,7 @@ from time import sleep
# PADDING = int(os.popen('tput cols').read()) // 3 # '// 2 - 6' for exact middle for n=4 # PADDING = int(os.popen('tput cols').read()) // 3 # '// 2 - 6' for exact middle for n=4
PADDING = 5 PADDING = 5
DEBUG = False DEBUG = False
ITER = -1
def get_board_dim(board: list) -> int: def get_board_dim(board: list) -> int:
return int(len(board) ** 0.5) return int(len(board) ** 0.5)
@ -60,36 +61,47 @@ def get_constraints(board: list, border: list, pos: int) -> list:
constraints = [colup, coldown, rowleft, rowright] constraints = [colup, coldown, rowleft, rowright]
return constraints return constraints
def check_constraint(slice: list, constraint: int, n: int) -> bool: def check_constraint(slice: list, constraint: int) -> bool:
global ITER
constraint = int(constraint) constraint = int(constraint)
if 0 in slice: peak = 0
return True
level = 0
visible_towers = 0 visible_towers = 0
# no board_dim in 0 to i-2 (inclusive) if slice[0] == 0:
# no board_dim-1 in 0 to i-3 return True
# no board_dim-2 in 0 to i-4
# no board_dim-3 in 0 to i-5
# ...
# no board_dim-i+2 in 0 to 0
board_dim = len(slice) board_dim = len(slice)
# print()
for i, tower in enumerate(slice): for i, tower in enumerate(slice):
if tower > level: if tower > peak:
level = tower peak = tower
visible_towers += 1 visible_towers += 1
if # print(f'{i=} {tower=} {peak=} {visible_towers=} {constraint=} {ITER=}')
return visible_towers == constraint if visible_towers > constraint:
return False
if constraint + tower > board_dim + 1 + i:
return False
if 0 not in slice:
return visible_towers == constraint
else:
return True
def is_valid_state(board: list, border: list, next_candidate_index: int) -> bool: def is_valid_state(board: list, border: list, next_candidate_index: int) -> bool:
global ITER
row = get_row(board, next_candidate_index) row = get_row(board, next_candidate_index)
column = get_col(board, next_candidate_index) column = get_col(board, next_candidate_index)
constraints = get_constraints(board, border, next_candidate_index) constraints = get_constraints(board, border, next_candidate_index)
ITER += 1
if ITER % 100000 == 0:
os.system('clear')
print_board(board, border)
print(f'{ITER=}')
satisfies_constraints = all([ satisfies_constraints = all([
check_constraint(column, constraints[0]), check_constraint(column, constraints[0]),
check_constraint(column[::-1], constraints[1]),
check_constraint(row, constraints[2]), check_constraint(row, constraints[2]),
check_constraint(column[::-1], constraints[1]),
check_constraint(row[::-1], constraints[3]), check_constraint(row[::-1], constraints[3]),
]) ])
return satisfies_constraints return satisfies_constraints
@ -156,11 +168,14 @@ def main(*args, **kwargs) -> None:
# print(solutions) # print(solutions)
if __name__ == '__main__': if __name__ == '__main__':
# main('1 1 1 1') # main('1 1 1 1') # 1 x 1
# main('2 1 1 2 2 1 1 2') # main('2 1 1 2 2 1 1 2') # 2 x 2
# main('3 2 1 1 2 2 3 2 1 1 2 2') # main('3 2 1 1 2 2 3 2 1 1 2 2') # 3 x 3
# main('4 3 2 1 1 2 2 2 4 3 2 1 1 2 2 2') # original problem # main('4 3 2 1 1 2 2 2 4 3 2 1 1 2 2 2') # original problem
# main('') # original problem
# main('3 2 2 1 1 2 1 1 4 2 1 2 1 2 2 2') # henri's problem # main('3 2 2 1 1 2 1 1 4 2 1 2 1 2 2 2') # henri's problem
# main('2 1 2 3 3 2 3 1 3 2 2 1 3 3 2 3 4 2 1 2') # main('2 1 2 3 3 2 3 1 3 2 2 1 3 3 2 3 4 2 1 2') # 5 x 5
# main('1 2 2 4 3 5 4 4 2 2 2 1 1 2 3 4 2 4 5 3 3 2 2 1') # main('1 2 2 4 3 5 4 4 2 2 2 1 1 2 3 4 2 4 5 3 3 2 2 1') # 6 x 6
# main('6 3 1 3 3 3 2 1 2 3 3 3 3 3 3 7 3 4 3 2 1 2 1 2 2 3 3 4') # main('6 3 1 3 3 3 2 1 2 3 3 3 3 3 3 7 3 4 3 2 1 2 1 2 2 3 3 4') # 7 x 7
# main('7 4 2 3 3 2 1 1 2 2 2 3 4 6 6 5 4 2 3 2 1 1 2 2 4 2 4 4') # 7 x 7
main('4 3 4 1 5 4 3 2 2 4 2 4 1 3 5 4 3 3 5 2 3 1 3 2 2 1 2 3 2 4 3 3') # 8 x 8