init-commit

This commit is contained in:
lilinyang 2025-05-23 15:27:15 +08:00
commit 18a552597a
3461 changed files with 1150579 additions and 0 deletions

View file

@ -0,0 +1,101 @@
def validate_campsite_solution(puzzle, row_constraints, col_constraints, solution):
"""
Checks if 'solution' is a valid solution to the given Campsite puzzle.
:param puzzle: 2D list (n×m), each cell is 'T' (tree) or 'X' (empty).
:param row_constraints: list of length n, how many tents should be in each row.
:param col_constraints: list of length m, how many tents should be in each column.
:param solution: 2D list (n×m), each cell is 'T', 'X', or 'C' (tent).
:return: (is_valid, message)
is_valid (bool) - True if the solution is valid, False otherwise
message (str) - Explanation if invalid, or "Valid solution" otherwise.
"""
n = len(puzzle)
m = len(puzzle[0])
# 1) Check the dimensions match
if len(solution) != n or any(len(row) != m for row in solution):
return False, "Solution dimension mismatch."
# 2) Puzzle 'T' must remain 'T' in the solution
for r in range(n):
for c in range(m):
if puzzle[r][c] == 'T' and solution[r][c] != 'T':
return False, f"Solution changed puzzle tree at row={r}, col={c}."
# Optionally, disallow new trees in puzzle 'X':
# If puzzle[r][c] == 'X' and solution[r][c] == 'T',
# you can decide how strict you want to be.
#
# Usually, in a Campsite puzzle, the trees are fixed,
# so we typically disallow adding new 'T' where puzzle was 'X'.
if puzzle[r][c] == 'X' and solution[r][c] == 'T':
return False, f"Solution introduced a new tree at row={r}, col={c}."
# 3) Check row/column counts of tents
row_counts = [0] * n
col_counts = [0] * m
for r in range(n):
for c in range(m):
if solution[r][c] == 'C':
row_counts[r] += 1
col_counts[c] += 1
for r in range(n):
if row_counts[r] != row_constraints[r]:
return False, f"Row {r} has {row_counts[r]} tents, expected {row_constraints[r]}."
for c in range(m):
if col_counts[c] != col_constraints[c]:
return False, f"Column {c} has {col_counts[c]} tents, expected {col_constraints[c]}."
# 4) Validate adjacency rules for tents
# (a) Each tent is orthogonally adjacent to at least one tree.
# (b) No two tents are adjacent in any of the 8 directions.
directions_orth = [(-1, 0), (1, 0), (0, -1), (0, 1)]
directions_diag = [(-1, -1), (-1, 1), (1, -1), (1, 1)]
directions_all = directions_orth + directions_diag
for r in range(n):
for c in range(m):
if solution[r][c] == 'C':
# (a) Ensure there's a tree in one of the orth. neighbors
has_tree_neighbor = False
for dr, dc in directions_orth:
rr, cc = r + dr, c + dc
if 0 <= rr < n and 0 <= cc < m and solution[rr][cc] == 'T':
has_tree_neighbor = True
break
if not has_tree_neighbor:
return False, f"Row={r}, Col={c} tent not adjacent to any tree."
# (b) Ensure no tent in any of the 8 directions
for dr, dc in directions_all:
rr, cc = r + dr, c + dc
if 0 <= rr < n and 0 <= cc < m:
if solution[rr][cc] == 'C':
return False, f"Tents at ({r},{c}) and ({rr},{cc}) are adjacent."
# If all checks pass
return True, "Valid solution."
if __name__ == "__main__":
puzzle = [
['X','X','X','T'],
['T','X','X','X'],
['X','X','T','X']
]
row_constraints = [1, 0, 2]
col_constraints = [1, 1, 0, 1]
solution = [
['C','X','X','T'], # A tent at (0,0)
['T','X','X','X'],
['X','C','T','C'] # A tent at (2,3)
]
is_valid, msg = validate_campsite_solution(puzzle, row_constraints, col_constraints, solution)
print(is_valid, msg)