input: Write a function to find the shortest path between two points in a given matrix. The function should return the length of the shortest path if a path exists, otherwise return -1. The matrix contains obstacles represented by 0's, and the path can move up, down, left, or right.
  def shortest_path(matrix, start, end):
    queue = []
    min_len = math.inf
    queue.append([start])
    while queue:
      path = queue.pop(0)
      x, y = path[-1]
      if (x, y) == end:
        if len(path) < min_len:
          min_len = len(path)
      for dx, dy in [[-1, 0], [1, 0], [0, -1], [0, 1]]:
        new_x, new_y = x + dx, y + dy
        if 0 <= new_x < len(matrix) and 0 <= new_y < len(matrix[0]):
          if matrix[new_x][new_y] == 0:
            queue.append(path + [(new_x, new_y)])
    return min_len if min_len != math.inf else -1
  
  assert shortest_path([[2, 3, 5], [1, 7, 6], [3, 0, 9]], (0, 0), (2, 2))==-1
  assert shortest_path([[2, 3, 5], [1, 7, 6], [3, 9, 9]], (0, 0), (2, 2))==5
  assert shortest_path([[2, 3], [1, 7]], (0, 0), (1, 1))==3
  assert shortest_path([[2, 3, 5], [1, 7, 6], [3, 9, 0]], (0, 0), (2, 2))==4
  assert shortest_path([[2, 3, 5], [1, 7, 6], [3, 9, 9]], (0, 0), (0, 0))==1
output: 
  def shortest_path(matrix, start, end):
    queue = []
    min_len = math.inf
    queue.append([start])
    while queue:
      path = queue.pop(0)
      x, y = path[-1]
      if (x, y) == end:
        if len(path) < min_len:
          min_len = len(path)
      for dx, dy in [[-1, 0], [1, 0], [0, -1], [0, 1]]:
        new_x, new_y = x + dx, y + dy
        if 0 <= new_x < len(matrix) and 0 <= new_y < len(matrix[0]):
          if matrix[new_x][new_y] != 0 and (new_x, new_y) not in path:
            queue.append(path + [(new_x, new_y)])
    return min_len if min_len != math.inf else -1
  