backtrack.py

This commit is contained in:
Timo Schmidt 2023-03-25 23:19:17 +01:00
parent 593444d10b
commit e217a701cb
1 changed files with 35 additions and 32 deletions

View File

@ -2,8 +2,11 @@
import os
import sys
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
DEBUG = False
def get_board_dim(board: list) -> int:
return int(len(board) ** 0.5)
@ -54,45 +57,41 @@ def get_constraints(board: list, border: list, pos: int) -> list:
coldown = border[row_idx + board_dim]
rowleft = border[col_idx + board_dim * 2]
rowright = border[col_idx + board_dim * 3]
# print(f'{board_dim=}, {pos=}, {col_idx=}, {row_idx=}')
# print(f'{colup=} {coldown=} {rowleft=} {rowright=}')
# print(f'{border=}')
constraints = [colup, coldown, rowleft, rowright]
return constraints
def check_constraint(slice: list, constraint: int) -> bool:
def check_constraint(slice: list, constraint: int, n: int) -> bool:
constraint = int(constraint)
print(f'{slice=}')
print(f'0 in slice: {0 in slice}')
print(f'{constraint=}')
if 0 in slice:
return True
level = 0
visible_towers = 0
for tower in slice:
# no board_dim in 0 to i-2 (inclusive)
# no board_dim-1 in 0 to i-3
# 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)
for i, tower in enumerate(slice):
if tower > level:
level = tower
visible_towers += 1
print(f'{visible_towers=} vs {constraint=}')
if
return visible_towers == constraint
def is_valid_state(board: list, border: list, next_candidate_index: int) -> bool:
print("################################ Calling is_valid_state function")
print(f'{next_candidate_index=}')
print_board(board, border)
row = get_row(board, next_candidate_index)
column = get_col(board, next_candidate_index)
constraints = get_constraints(board, border, next_candidate_index)
print(f'{constraints=}, {row=}, {column=}')
satisfies_constraints = all([
check_constraint(column, constraints[0]),
check_constraint(column[::-1], constraints[1]),
check_constraint(row, constraints[2]),
check_constraint(row[::-1], constraints[3]),
check_constraint(column, constraints[0]),
check_constraint(column[::-1], constraints[1])
])
print(f'{satisfies_constraints=}')
print("################################ Finished is_valid_state function")
print()
return satisfies_constraints
def print_board(board: list, border: list) -> None:
@ -111,27 +110,25 @@ def print_board(board: list, border: list) -> None:
print(' '.join(border[board_dim:board_dim * 2]))
print()
# 2D board initialized with 0's, dependent on n
# params: rec-depth, n, **board, **border
def backtrack(board: list, sols: list, border: list) -> None:
def backtrack_skyscrapers(board: list, sols: list, border: list) -> None:
if board.count(0) == 0:
sols.append(board)
print("Solutions")
print_board(sols[0], border)
print("Done")
sys.exit(0)
next_candidate_index = board.index(0)
candidates = get_candidates(board, next_candidate_index)
for candidate in candidates:
board[next_candidate_index] = candidate
print(f'Current candidate: {next_candidate_index}')
if DEBUG:
# sleep(2)
input()
os.system('clear')
print_board(board, border)
if is_valid_state(board, border, next_candidate_index):
backtrack(board, sols, border)
print(f"Setting board at {next_candidate_index} to 0")
backtrack_skyscrapers(board, sols, border)
board[next_candidate_index] = 0
def main(*args, **kwargs) -> None:
if kwargs:
print('Error (kwargs)')
sys.exit(1)
@ -155,9 +152,15 @@ def main(*args, **kwargs) -> None:
0 for _ in range(board_dim ** 2)
]
solutions = []
backtrack(board, solutions, border)
print(solutions)
backtrack_skyscrapers(board, solutions, border)
# print(solutions)
if __name__ == '__main__':
sys.exit(main('4 3 2 1 1 2 2 2 4 3 2 1 1 2 2 2'))
# sys.exit(main(('0 ' * 81)[:-1]))
# main('1 1 1 1')
# main('2 1 1 2 2 1 1 2')
# main('3 2 1 1 2 2 3 2 1 1 2 2')
# main('4 3 2 1 1 2 2 2 4 3 2 1 1 2 2 2') # original 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('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('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')