[Golang] A-Star
\ntype State struct {\n    Box []int\n    Person []int\n    TotalDistanceToTarget int\n    DistanceToBox int\n    Moves int\n}\n\nfunc minPushBox(grid [][]byte)
```\ntype State struct {\n    Box []int\n    Person []int\n    TotalDistanceToTarget int\n    DistanceToBox int\n    Moves int\n}\n\nfunc minPushBox(grid [][]byte) int {\n    m := len(grid)\n    n := len(grid[0])\n    \n    visited := make(map[string]bool)\n    var target, box, person []int\n    for r := 0; r < m; r++ {\n        for c := 0; c < n; c++ {\n            if grid[r][c] == \'S\' {\n                person = []int{r, c}\n            } else if grid[r][c] == \'B\' {\n                box = []int{r, c}\n            } else if grid[r][c] == \'T\' {\n                target = []int{r, c}\n            }\n        }\n    }\n    \n    minHeap := &MinHeap{}\n    heap.Push(minHeap, State{box, person, calculateDistance(box, target), calculateDistance(box, person), 0})\n    \n    for minHeap.Len() > 0 {\n        state := heap.Pop(minHeap).(State)\n        currBox := state.Box\n        currPerson := state.Person\n        \n        if currBox[0] == target[0] && currBox[1] == target[1] {\n            return state.Moves\n        }\n        \n        key := fmt.Sprintf("%d-%d-%d-%d", currBox[0], currBox[1], currPerson[0], currPerson[1])\n\n        if visited[key] {\n            continue\n        }\n        visited[key] = true\n        \n        for _, dir := range [][]int{{-1, 0}, {1, 0}, {0, -1}, {0, 1}} {\n            newPerson := []int{currPerson[0] + dir[0], currPerson[1] + dir[1]}\n            if !ValidMove(newPerson, grid) {\n                continue\n            }\n            \n            // Now person may come on Box Cell, which is like pushing Box\n            if currBox[0] == newPerson[0] && currBox[1] == newPerson[1] {\n                newBox := []int{currBox[0] + dir[0], currBox[1] + dir[1]}\n                if !ValidMove(newBox, grid) {\n                    continue\n                }\n                heap.Push(minHeap, State{newBox, newPerson, calculateDistance(newBox, target)+state.Moves+1, calculateDistance(newBox, newPerson), state.Moves+1})\n            } else {\n                heap.Push(minHeap, State{currBox, newPerson, state.TotalDistanceToTarget, calculateDistance(currBox, newPerson), state.Moves})\n            }\n        }\n    }\n    \n    return -1\n}\n\nfunc calculateDistance(start, end []int) int {\n    return abs(start[0]-end[0]) + abs(start[1]-end[1])\n}\n\nfunc ValidMove(cell []int, grid [][]byte) bool {\n    r := cell[0]\n    c := cell[1]\n    if r < 0 || r == len(grid) || c < 0 || c == len(grid[0]) || grid[r][c] == \'#\' {\n        return false\n    }\n    return true\n}\n\nfunc abs(a int) int {\n    if a < 0 {\n        return -a\n    }\n    return a\n}\n\ntype MinHeap []State\n\nfunc (h MinHeap) Len() int {\n    return len(h)\n}\n\nfunc (h MinHeap) Less(i int, j int) bool {\n    if h[i].TotalDistanceToTarget == h[j].TotalDistanceToTarget {\n        return h[i].DistanceToBox < h[j].DistanceToBox\n    }\n    return h[i].TotalDistanceToTarget < h[j].TotalDistanceToTarget\n}\n                          \nfunc (h MinHeap) Swap(i int, j int) {\n    h[i], h[j] = h[j], h[i]\n} \n                          \nfunc (h *MinHeap) Push(a interface{}) {\n    *h = append(*h, a.(State))\n}\n\nfunc (h *MinHeap) Pop() interface{} {\n    l := len(*h)\n    res := (*h)[l - 1]\n    *h = (*h)[:l - 1]\n    return res\n}\n```
['Go']