Skip to content

Instantly share code, notes, and snippets.

@KirillLykov
Last active September 19, 2021 07:20
Show Gist options
  • Save KirillLykov/57670f13da1e4cc7d2dddd469b44a157 to your computer and use it in GitHub Desktop.
Save KirillLykov/57670f13da1e4cc7d2dddd469b44a157 to your computer and use it in GitHub Desktop.
Leetcode Move A Box To Target Location
// further readings: http://forskning.diku.dk/PATH05/GoldbergSlides.pdf
// problem itself https://leetcode.com/problems/minimum-moves-to-move-a-box-to-their-target-location/
class Solution {
public:
using State = tuple<int,int,int,int>; // xbox, ybox, xme, yme
static constexpr int x[] = {1,-1,0,0};
static constexpr int y[] = {0,0, 1, -1};
bool impossible(vector<vector<char>>& grid, const pair<int,int>& pos) {
if (pos.first < 0 || pos.first >= grid.size() ||
pos.second < 0 || pos.second >= grid[0].size() ||
grid[pos.first][pos.second] == '#')
return true;
return false;
}
void getInitialStateAndTarget(vector<vector<char>>& grid,
State& state, pair<int,int>& target)
{
for (int i = 0; i < grid.size(); ++i)
for (int j = 0; j < grid[i].size(); ++j) {
if (grid[i][j] == 'B') {
get<0>(state) = i;
get<1>(state) = j;
}
if (grid[i][j] == 'S') {
get<2>(state) = i;
get<3>(state) = j;
}
if (grid[i][j] == 'T') {
target = {i, j};
}
}
}
int minPushBox(vector<vector<char>>& grid) {
State start;
pair<int,int> target;
getInitialStateAndTarget(grid, start, target);
vector<vector<State>> q;
q.emplace_back(vector<State>{start});
// lazy to define hash
set<State> visited;
map<State, int> dist;
for (int d = 0; d < q.size(); ++d) {
for (int i = 0; i < q[d].size(); ++i) {
auto[xbox,ybox,xme,yme] = q[d][i];
if (xbox == target.first && ybox == target.second)
return dist[q[d][i]];
if (visited.count(q[d][i])) continue;
visited.emplace(q[d][i]);
for (int idir = 0; idir < 4; ++idir) {
pair<int,int> newMe{xme + x[idir],
yme + y[idir]};
if (impossible(grid, newMe)) continue;
int edgeWeight = 0;
pair<int,int> newBox{xbox, ybox};
if (newMe == pair<int,int>{xbox, ybox}) {
edgeWeight = 1;
newBox = pair<int,int>{xbox + x[idir], ybox + y[idir]};
if (impossible(grid, {xbox, ybox})) continue;
}
State newState{newBox.first, newBox.second, newMe.first, newMe.second};
int newDist = dist[q[d][i]] + edgeWeight;
if (dist.count(newState) == 0 ||
dist[newState] > newDist) {
dist[newState] = newDist;
while (newDist >= q.size())
q.emplace_back(vector<State>{});
q[newDist].emplace_back(newState);
}
}
}
}
return -1;
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment