| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #include <bits/stdc++.h> |
| using namespace std; |
|
|
| constexpr long long P = 998244353; |
|
|
| |
| |
| |
|
|
| struct Program { |
| int n; |
| int type[30]; |
| int pop_c[30]; |
| int goto1[30]; |
| int push_c[30]; |
| int goto2[30]; |
|
|
| optional<pair<int, long long>> dp[30][40]; |
| bool vis[30][40]; |
| bool inf; |
| int maxC; |
|
|
| void clear_dp() { |
| for (int i = 0; i < n; i++) |
| for (int j = 0; j <= maxC; j++) { |
| dp[i][j].reset(); |
| vis[i][j] = false; |
| } |
| inf = false; |
| } |
|
|
| pair<int, long long> solve(int i, int x) { |
| if (dp[i][x]) return dp[i][x].value(); |
| if (vis[i][x]) { inf = true; return {-1, 0}; } |
| vis[i][x] = true; |
|
|
| if (type[i] == 0) { |
| if (x == pop_c[i]) { |
| dp[i][x] = {goto1[i], 1LL}; |
| } else { |
| auto [j, u] = solve(goto2[i], push_c[i]); |
| if (inf) return {-1, 0}; |
| auto [k, v] = solve(j, x); |
| if (inf) return {-1, 0}; |
| dp[i][x] = {k, (u + v + 1) % P}; |
| } |
| } else { |
| if (x == 0) { |
| dp[i][x] = {-1, 1LL}; |
| } else { |
| auto [j, u] = solve(goto2[i], push_c[i]); |
| if (inf) return {-1, 0}; |
| auto [k, v] = solve(j, x); |
| if (inf) return {-1, 0}; |
| dp[i][x] = {k, (u + v + 1) % P}; |
| } |
| } |
| return dp[i][x].value(); |
| } |
|
|
| long long eval() { |
| clear_dp(); |
| auto [fi, steps] = solve(0, 0); |
| if (inf) return -1; |
| return steps; |
| } |
| }; |
|
|
| int main() { |
| long long target1 = 150994941; |
| long long target2 = 150994939; |
|
|
| mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| for (int d = 15; d <= 26; d++) { |
| int n = d + 1; |
| Program prog; |
| prog.n = n; |
| int maxPushChar = d + 3; |
| prog.maxC = maxPushChar; |
|
|
| fprintf(stderr, "=== d=%d (n=%d, maxC=%d) ===\n", d, n, maxPushChar); |
|
|
| auto dStart = chrono::steady_clock::now(); |
| auto dElapsed = [&]() { |
| return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - dStart).count(); |
| }; |
|
|
| bool found = false; |
|
|
| for (int restart = 0; dElapsed() < 8000 && !found; restart++) { |
| |
| for (int j = 0; j < d; j++) { |
| prog.type[j] = 0; |
| prog.pop_c[j] = j + 1; |
| prog.goto1[j] = j + 1; |
| prog.push_c[j] = 1 + rng() % maxPushChar; |
| prog.goto2[j] = rng() % n; |
| } |
| prog.type[d] = 1; |
| prog.push_c[d] = 1 + rng() % maxPushChar; |
| prog.goto2[d] = rng() % n; |
|
|
| long long T = prog.eval(); |
| if (T < 0) continue; |
|
|
| for (int iter = 0; iter < 300000 && !found; iter++) { |
| if (T == target1 || T == target2) { |
| found = true; |
| fprintf(stderr, "FOUND! d=%d n=%d T=%lld\n", d, n, T); |
| printf("%d\n", n); |
| for (int j = 0; j < d; j++) { |
| printf("POP %d GOTO %d PUSH %d GOTO %d\n", |
| prog.pop_c[j], prog.goto1[j]+1, prog.push_c[j], prog.goto2[j]+1); |
| } |
| printf("HALT PUSH %d GOTO %d\n", prog.push_c[d], prog.goto2[d]+1); |
| break; |
| } |
|
|
| |
| int j = rng() % n; |
| int what = rng() % 3; |
| int sv_push = prog.push_c[j], sv_g2 = prog.goto2[j], sv_g1 = prog.goto1[j]; |
|
|
| if (what == 0) prog.push_c[j] = 1 + rng() % maxPushChar; |
| else if (what == 1) prog.goto2[j] = rng() % n; |
| else if (j < d) prog.goto1[j] = rng() % n; |
|
|
| long long nT = prog.eval(); |
| if (nT < 0) { |
| prog.push_c[j] = sv_push; prog.goto2[j] = sv_g2; prog.goto1[j] = sv_g1; |
| continue; |
| } |
|
|
| long long nd1 = min((nT - target1 + P) % P, (target1 - nT + P) % P); |
| long long od1 = min((T - target1 + P) % P, (target1 - T + P) % P); |
| long long nd2 = min((nT - target2 + P) % P, (target2 - nT + P) % P); |
| long long od2 = min((T - target2 + P) % P, (target2 - T + P) % P); |
| long long best_nd = min(nd1, nd2); |
| long long best_od = min(od1, od2); |
|
|
| if (best_nd <= best_od) T = nT; |
| else { |
| prog.push_c[j] = sv_push; prog.goto2[j] = sv_g2; prog.goto1[j] = sv_g1; |
| } |
| } |
|
|
| if (restart % 200 == 0 && restart > 0) |
| fprintf(stderr, "d=%d restart=%d elapsed=%ldms\n", d, restart, dElapsed()); |
| } |
|
|
| if (found) return 0; |
| } |
|
|
| return 0; |
| } |
|
|