diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..cfe2cf1 --- /dev/null +++ b/Makefile @@ -0,0 +1,9 @@ +CC=g++ +INCLUDE_DIR=include +CFLAGS=-std=c++17 -fopenmp -Wall -O3 -march=native -I $(INCLUDE_DIR) + +box-eater: optimizer/box-eater.cpp + $(CC) $(CFLAGS) -o $@ $^ + +box-breaker: optimizer/box-breaker.cpp + $(CC) $(CFLAGS) -o $@ $^ diff --git a/optimizer/box-solver.h b/include/box-solver.h similarity index 100% rename from optimizer/box-solver.h rename to include/box-solver.h diff --git a/optimizer/pushbox.h b/include/pushbox.h similarity index 100% rename from optimizer/pushbox.h rename to include/pushbox.h diff --git a/optimizer/box-breaker.cpp b/optimizer/box-breaker.cpp index 904e201..cb00c81 100644 --- a/optimizer/box-breaker.cpp +++ b/optimizer/box-breaker.cpp @@ -1,167 +1,19 @@ #include +#include "pushbox.h" +#include "box-solver.h" using namespace std; -const int N = 20; - mt19937 rng(random_device{}()); uniform_real_distribution d01(0, 1); uniform_int_distribution rng10(0, 9); uniform_int_distribution rngN(0, 19); -enum { - POI_PERSON, - POI_BOX, - POI_TARGET, - POI_EXCEED, -}; - #define compiler_assume(condition) \ do { \ if (!(condition)) \ __builtin_unreachable(); \ } while (false); \ -struct Maze { - bitset M[N]; - int poi[3][2]; - - int at(int x, int y) const { - return M[x][y]; - } - - void set(int x, int y, int v) { - M[x][y] = v; - } - - void flip(int x, int y) { - M[x].flip(y); - } - - bool isValid() const { - for (int i = 0; i < POI_EXCEED; ++i) { - for (int j : {0, 1}) { - if (poi[i][j] < 0 || poi[i][j] >= N) - return false; - } - - if (at(poi[i][0], poi[i][1]) == 0) - return false; - } - return true; - } -}; - -inline Maze loadMaze(std::FILE *f) { - char *s = new char[N + 5]; - Maze res; - for (int i = 0; i < N; ++i) { - std::fscanf(f, "%s", s); - for (int j = 0; j < N; ++j) { - res.set(i, j, s[j] != '#'); - switch (s[j]) { - case 'P': - res.poi[POI_PERSON][0] = i; - res.poi[POI_PERSON][1] = j; - break; - case '*': - res.poi[POI_BOX][0] = i; - res.poi[POI_BOX][1] = j; - break; - case 'O': - res.poi[POI_TARGET][0] = i; - res.poi[POI_TARGET][1] = j; - break; - } - } - } - delete[] s; - return res; -} - -inline void writeMaze(const Maze &m, std::FILE *f) { - for (int i = 0; i < N; ++i) { - for (int j = 0; j < N; ++j) { - if (i == m.poi[POI_PERSON][0] && j == m.poi[POI_PERSON][1]) - std::fputc('P', f); - else if (i == m.poi[POI_BOX][0] && j == m.poi[POI_BOX][1]) - std::fputc('*', f); - else if (i == m.poi[POI_TARGET][0] && j == m.poi[POI_TARGET][1]) - std::fputc('O', f); - else if (m.at(i, j) == 0) - std::fputc('#', f); - else - std::fputc('.', f); - } - std::fputc('\n', f); - } -} - -namespace Solve { -bitset mp[N]; -int dis[N][N][N][N]; -queue> qu; - -inline int bfs(int px, int py, int bx, int by, int tx, int ty) { - memset(dis, 127, sizeof(dis)); - while (!qu.empty()) - qu.pop(); - - auto expand = [&](int npx, int npy, int nbx, int nby, int d) { - if (npx < 0 || npx >= N) - return; - if (npy < 0 || npy >= N) - return; - if (nbx < 0 || nbx >= N) - return; - if (nby < 0 || nby >= N) - return; - if (mp[npx][npy] == 0) - return; - if (mp[nbx][nby] == 0) - return; - if (npx == nbx && npy == nby) - return; - - if (dis[npx][npy][nbx][nby] <= d) - return; - dis[npx][npy][nbx][nby] = d; - qu.emplace(npx, npy, nbx, nby); - }; - - expand(px, py, bx, by, 0); - - while (!qu.empty()) { - auto [npx, npy, nbx, nby] = qu.front(); - int d = dis[npx][npy][nbx][nby]; - qu.pop(); - - if (nbx == tx && nby == ty) - return d; - - expand(npx + 1, npy, nbx, nby, d + 1); - expand(npx - 1, npy, nbx, nby, d + 1); - expand(npx, npy + 1, nbx, nby, d + 1); - expand(npx, npy - 1, nbx, nby, d + 1); - if (npx + 1 == nbx && npy == nby) - expand(npx + 1, npy, nbx + 1, nby, d + 1); - if (npx - 1 == nbx && npy == nby) - expand(npx - 1, npy, nbx - 1, nby, d + 1); - if (npx == nbx && npy + 1 == nby) - expand(npx, npy + 1, nbx, nby + 1, d + 1); - if (npx == nbx && npy - 1 == nby) - expand(npx, npy - 1, nbx, nby - 1, d + 1); - } - return -1; -} - -inline int solve(Maze q) { - for (int i = 0; i < 20; ++i) - mp[i] = q.M[i]; - return bfs(q.poi[POI_PERSON][0], q.poi[POI_PERSON][1] - , q.poi[POI_BOX][0], q.poi[POI_BOX][1], q.poi[POI_TARGET][0], q.poi[POI_TARGET][1]); -} -}; // namespace Solve - const float initial_temperature = 10; const float initial_temperature_pv = 60; const float termperature_delta = .97;