input: Write a python function to solve the 8-puzzle problem.
  assert solve_8_puzzle([[1, 2, 3], [8, 0, 4], [7, 6, 5]])['state']==[[1, 2, 3], [8, 0, 4], [7, 6, 5]]
  assert solve_8_puzzle([[1, 2, 3], [8, 4, 0], [7, 6, 5]])['state']==[[1, 2, 3], [8, 0, 4], [7, 6, 5]]
  assert solve_8_puzzle([[4, 1, 3], [8, 2, 0], [7, 6, 5]])['state']==[[1, 2, 3], [8, 0, 4], [7, 6, 5]]
output: from heapq import heappop, heappush
  
  def solve_8_puzzle(start):
      goal = [[1, 2, 3], [8, 0, 4], [7, 6, 5]]
      goal_pos = {goal[i][j]: (i, j) for i in range(3) for j in range(3)}
      
      def heuristic(state):
          return sum(abs(i - goal_pos[val][0]) + abs(j - goal_pos[val][1])
                     for i, row in enumerate(state) for j, val in enumerate(row) if val != 0)
      
      def get_neighbors(state):
          neighbors = []
          zero_pos = [(i, j) for i in range(3) for j in range(3) if state[i][j] == 0][0]
          i, j = zero_pos
          for di, dj in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
              ni, nj = i + di, j + dj
              if 0 <= ni < 3 and 0 <= nj < 3:
                  new_state = [row[:] for row in state]
                  new_state[i][j], new_state[ni][nj] = new_state[ni][nj], new_state[i][j]
                  neighbors.append(new_state)
          return neighbors
      
      def state_to_tuple(state):
          return tuple(tuple(row) for row in state)
      
      open_set = []
      heappush(open_set, (heuristic(start), 0, start, None))
      came_from = {}
      g_score = {state_to_tuple(start): 0}
      
      while open_set:
          _, curr_g, current, parent = heappop(open_set)
          if current == goal:
              return {'state': current}
          
          current_tuple = state_to_tuple(current)
          came_from[current_tuple] = parent
          
          for neighbor in get_neighbors(current):
              neighbor_tuple = state_to_tuple(neighbor)
              tentative_g_score = curr_g + 1
              if tentative_g_score < g_score.get(neighbor_tuple, float('inf')):
                  g_score[neighbor_tuple] = tentative_g_score
                  f_score = tentative_g_score + heuristic(neighbor)
                  heappush(open_set, (f_score, tentative_g_score, neighbor, current_tuple))
      
      return {'state': None}  # In case no solution is found