mirror of
https://github.com/InternLM/InternBootcamp.git
synced 2026-04-19 12:58:04 +00:00
101 lines
No EOL
3.9 KiB
Python
Executable file
101 lines
No EOL
3.9 KiB
Python
Executable file
|
||
|
||
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) |