mirror of
https://github.com/InternLM/InternBootcamp.git
synced 2026-04-19 12:58:04 +00:00
init-commit
This commit is contained in:
commit
18a552597a
3461 changed files with 1150579 additions and 0 deletions
218
internbootcamp/libs/arrowmaze/maze_validor.py
Executable file
218
internbootcamp/libs/arrowmaze/maze_validor.py
Executable file
|
|
@ -0,0 +1,218 @@
|
|||
import re
|
||||
|
||||
def parse_candidate_path(answer_str):
|
||||
"""
|
||||
Parse a candidate_path string in the format:
|
||||
"[[1 0 0,0 0 0,0 0 2]]"
|
||||
into a 2D list of integers.
|
||||
"""
|
||||
# 1) Remove the outer brackets "[[" and "]]"
|
||||
# 2) Split into rows by comma
|
||||
# 3) Each row is space-separated integers
|
||||
# Example input: "[[1 0 0,0 0 0,0 0 2]]"
|
||||
|
||||
# Trim leading/trailing brackets
|
||||
trimmed = answer_str.strip()
|
||||
if trimmed.startswith("[["):
|
||||
trimmed = trimmed[2:]
|
||||
if trimmed.endswith("]]"):
|
||||
trimmed = trimmed[:-2]
|
||||
|
||||
# Now we have something like: "1 0 0,0 0 0,0 0 2"
|
||||
# Split by commas to get rows
|
||||
row_strs = trimmed.split(",")
|
||||
|
||||
grid_of_ints = []
|
||||
for row_str in row_strs:
|
||||
# row_str might look like "1 0 0" or "0 0 2"
|
||||
row_str = row_str.strip()
|
||||
if not row_str:
|
||||
continue
|
||||
# split by spaces
|
||||
vals = row_str.split()
|
||||
row_ints = [int(v) for v in vals]
|
||||
grid_of_ints.append(row_ints)
|
||||
return grid_of_ints
|
||||
|
||||
def arrow_maze_validator(
|
||||
grid, start_position, answer
|
||||
):
|
||||
"""
|
||||
Validate whether a candidate_path in puzzle's format (e.g. "[[1 0 0,0 0 0,0 0 2]]")
|
||||
is a correct solution to the arrow maze.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
grid : list[list[str]]
|
||||
A 2D grid of arrow symbols or '○'.
|
||||
Example:
|
||||
[
|
||||
['→', '↙', '↓'],
|
||||
['↖', '↓', '↙'],
|
||||
['↑', '←', '○'],
|
||||
]
|
||||
start_position : (int, int)
|
||||
(row, col) of the starting cell.
|
||||
answer : list
|
||||
The proposed solution in the format "[[...]]"
|
||||
0 => not on path
|
||||
1 => first visited cell
|
||||
2 => second visited cell
|
||||
etc.
|
||||
|
||||
Returns
|
||||
-------
|
||||
bool
|
||||
True if the path is valid, False otherwise.
|
||||
"""
|
||||
|
||||
# Directions dictionary: maps arrow symbol -> (dr, dc)
|
||||
DIRECTIONS = {
|
||||
'↑': (-1, 0),
|
||||
'↓': ( 1, 0),
|
||||
'←': ( 0, -1),
|
||||
'→': ( 0, 1),
|
||||
'↖': (-1, -1),
|
||||
'↗': (-1, 1),
|
||||
'↙': ( 1, -1),
|
||||
'↘': ( 1, 1),
|
||||
}
|
||||
|
||||
rows = len(grid)
|
||||
cols = len(grid[0]) if rows > 0 else 0
|
||||
|
||||
def in_bounds(r, c):
|
||||
return 0 <= r < rows and 0 <= c < cols
|
||||
|
||||
|
||||
#$candidate_grid = parse_candidate_path(answer_str)
|
||||
candidate_grid = answer
|
||||
|
||||
# Sanity check: the candidate_grid should match the same dimensions as 'grid'
|
||||
if len(candidate_grid) != rows:
|
||||
return False
|
||||
for row_vals in candidate_grid:
|
||||
if len(row_vals) != cols:
|
||||
return False
|
||||
|
||||
# 2. Extract the labeled cells: (label, (row, col))
|
||||
# We only care about label > 0
|
||||
labeled_cells = []
|
||||
for r in range(rows):
|
||||
for c in range(cols):
|
||||
label = candidate_grid[r][c]
|
||||
if label > 0:
|
||||
labeled_cells.append((label, (r, c)))
|
||||
|
||||
# If no labeled cells, invalid
|
||||
if not labeled_cells:
|
||||
return False
|
||||
|
||||
# 3. Sort by label ascending
|
||||
labeled_cells.sort(key=lambda x: x[0]) # sort by label number
|
||||
# This gives us an ordered path: [ (1, (r1,c1)), (2, (r2,c2)), ... ]
|
||||
|
||||
# 4. The path in terms of coordinates:
|
||||
path = [cell_coord for _, cell_coord in labeled_cells]
|
||||
|
||||
# 5. Check that label "1" is at start_position
|
||||
if path[0] != start_position:
|
||||
return False
|
||||
|
||||
# 6. Validate each consecutive step in path
|
||||
for i in range(len(path) - 1):
|
||||
(r1, c1) = path[i]
|
||||
(r2, c2) = path[i + 1]
|
||||
|
||||
if not in_bounds(r1, c1) or not in_bounds(r2, c2):
|
||||
return False
|
||||
|
||||
# If the current cell is the end symbol '○' but we still have more steps, invalid
|
||||
if grid[r1][c1] == '○':
|
||||
return False
|
||||
|
||||
# Arrow in the current cell:
|
||||
arrow_symbol = grid[r1][c1]
|
||||
if arrow_symbol not in DIRECTIONS:
|
||||
return False # not an arrow and not the end symbol
|
||||
|
||||
(dr, dc) = DIRECTIONS[arrow_symbol]
|
||||
delta_r = r2 - r1
|
||||
delta_c = c2 - c1
|
||||
|
||||
# Must move in a positive integer multiple of (dr, dc).
|
||||
if dr == 0 and dc == 0:
|
||||
return False # shouldn't happen with valid arrows
|
||||
|
||||
# Horizontal or vertical
|
||||
if dr == 0:
|
||||
# vertical movement is zero => must move horizontally
|
||||
# check we didn't move in row, must move in col
|
||||
if delta_r != 0:
|
||||
return False
|
||||
# direction must match sign of dc
|
||||
if dc > 0 and delta_c <= 0:
|
||||
return False
|
||||
if dc < 0 and delta_c >= 0:
|
||||
return False
|
||||
elif dc == 0:
|
||||
# horizontal movement is zero => must move in row
|
||||
if delta_c != 0:
|
||||
return False
|
||||
if dr > 0 and delta_r <= 0:
|
||||
return False
|
||||
if dr < 0 and delta_r >= 0:
|
||||
return False
|
||||
else:
|
||||
# diagonal
|
||||
if delta_r == 0 or delta_c == 0:
|
||||
return False # can't be diagonal if one is zero
|
||||
if (dr > 0 and delta_r <= 0) or (dr < 0 and delta_r >= 0):
|
||||
return False
|
||||
if (dc > 0 and delta_c <= 0) or (dc < 0 and delta_c >= 0):
|
||||
return False
|
||||
# check integer multiples
|
||||
if (delta_r % dr) != 0 or (delta_c % dc) != 0:
|
||||
return False
|
||||
factor_r = delta_r // dr
|
||||
factor_c = delta_c // dc
|
||||
if factor_r != factor_c or factor_r <= 0:
|
||||
return False
|
||||
|
||||
# 7. Check last labeled cell is the '○' cell
|
||||
last_r, last_c = path[-1]
|
||||
if not in_bounds(last_r, last_c):
|
||||
return False
|
||||
if grid[last_r][last_c] != '○':
|
||||
return False
|
||||
|
||||
# If all checks pass, it's a valid solution
|
||||
return True
|
||||
|
||||
|
||||
# ------------------------------
|
||||
# Example usage:
|
||||
if __name__ == "__main__":
|
||||
# A small 3×3 arrow maze with start=(0, 0):
|
||||
# Grid (3x3):
|
||||
# → ↙ ↓
|
||||
# ↖ ↓ ↙
|
||||
# ↑ ← ○
|
||||
grid = [
|
||||
['→', '↙', '↓'],
|
||||
['↖', '↓', '↙'],
|
||||
['↑', '←', '○'],
|
||||
]
|
||||
start_position = (0, 0)
|
||||
|
||||
# Example candidate_path string:
|
||||
# "[[1 0 0,0 0 0,0 0 2]]"
|
||||
# This claims:
|
||||
# row=0 col=0 => 1 (start)
|
||||
# row=2 col=2 => 2 (end)
|
||||
candidate_path_str = "[[1 0 2,0 0 0,0 0 3]]"
|
||||
|
||||
is_valid = arrow_maze_validator(
|
||||
grid, start_position, candidate_path_str
|
||||
)
|
||||
print("Is the candidate path valid?", is_valid)
|
||||
Loading…
Add table
Add a link
Reference in a new issue