py_prism_detector

Código comentado línea a línea y paso a paso:

Entregas: py_prism_detector.py con prism_detector(grid, pattern). Rank 05 · nivel 3.

Qué pide (en palabras normales)

Subject (enunciado original)
Write a function that searches for all occurrences of a target word pattern within a 2D grid of characters in all 8 cardinal and diagonal directions.

The directions and their codes are:
- (1, 0) -> "H" (Horizontal right)
- (-1, 0) -> "H-" (Horizontal left)
- (0, 1) -> "V" (Vertical down)
- (0, -1) -> "V-" (Vertical up)
- (1, 1) -> "D1" (Diagonal down-right)
- (-1, -1) -> "D1-" (Diagonal up-left)
- (-1, 1) -> "D2" (Diagonal up-right)
- (1, -1) -> "D2-" (Diagonal down-left)

The function should:
- Take a grid of strings `grid` and a target string `pattern`.
- Return a list of tuples `(x, y, direction_code)` for each match, where `x` is the column index and `y` is the row index of the first character.
- Return an empty list `[]` if either `grid` or `pattern` is empty.

Expected file: py_prism_detector.py
Function signature:
def prism_detector(grid: list[str], pattern: str):

Examples:
prism_detector(["CAT", "A..", "T.."], "CAT")
=> [(0, 0, "H"), (0, 0, "V")]
prism_detector([], "CAT")
=> []

La tabla de direcciones

DIRECTIONS = [
    (1, 0, "H"), (-1, 0, "H-"),
    (0, 1, "V"), (0, -1, "V-"),
    (1, 1, "D1"), (-1, -1, "D1-"),
    (-1, 1, "D2"), (1, -1, "D2-"),
]

Copiada literal del subject, mismo orden. Los códigos son el 90% del ejercicio: un `D2` mal puesto y fallas tests que por lógica estarían bien. Fíjate en que D2 es (-1, 1): x hacia la izquierda, y hacia abajo, aunque se llame "up-right".

Comprobar un rayo

def matches(grid, pattern, x, y, dx, dy):
    for ch in pattern:
        if not (0 <= y < len(grid) and 0 <= x < len(grid[y])) or grid[y][x] != ch:
            return False
        x += dx
        y += dy
    return True

Desde la celda inicial avanzo letra a letra. Si me salgo o la letra no coincide, no hay match. Límites antes de indexar: grid[-1] no da error en Python, da la última fila, y te inventa coincidencias.

El bucle principal

for y in range(rows):
    for x in range(len(grid[y])):
        if grid[y][x] != pattern[0]:
            continue
        for dx, dy, code in DIRECTIONS:
            if matches(grid, pattern, x, y, dx, dy):
                found.append((x, y, code))

Filas por fuera, columnas por dentro, direcciones en el orden de la tabla: así la salida sale en el mismo orden que el ejemplo [(0, 0, "H"), (0, 0, "V")].

Trampas