| #include <bits/stdc++.h> |
| using namespace std; |
|
|
| struct Instr { |
| int type; |
| int a, x, b, y; |
| }; |
|
|
| int main() { |
| ios::sync_with_stdio(false); |
| cin.tie(nullptr); |
| |
| long long k; |
| if (!(cin >> k)) return 0; |
|
|
| vector<Instr> prog; |
|
|
| auto add_pop = [&](int a, int x, int b, int y) { |
| Instr ins; |
| ins.type = 0; |
| ins.a = a; ins.x = x; ins.b = b; ins.y = y; |
| prog.push_back(ins); |
| return (int)prog.size(); |
| }; |
| auto add_halt = [&](int b, int y) { |
| Instr ins; |
| ins.type = 1; |
| ins.b = b; ins.y = y; |
| prog.push_back(ins); |
| return (int)prog.size(); |
| }; |
|
|
| if (k == 1) { |
| cout << 1 << "\n"; |
| cout << "HALT PUSH 1 GOTO 1\n"; |
| return 0; |
| } |
| if (k == 3) { |
| cout << 2 << "\n"; |
| cout << "POP 2 GOTO 2 PUSH 2 GOTO 1\n"; |
| cout << "HALT PUSH 1 GOTO 2\n"; |
| return 0; |
| } |
|
|
| |
| |
| |
| int S = 1; |
| int nextSym = 2; |
|
|
| |
| int init_idx = add_pop(S, 0, S, 0); |
|
|
| |
| long long T = (k - 5) / 2; |
| int H = (int)(T & 1); |
| |
| |
| vector<pair<int,int>> segments; |
| int prev_halt = 0; |
|
|
| auto add_block_i = [&](int i) { |
| int entry = (int)prog.size() + 1; |
| int cur_entry = entry; |
| |
| vector<int> tokens; |
| for (int j = 0; j < i; ++j) { |
| int tok = nextSym++; |
| tokens.push_back(tok); |
| } |
| for (int j = 0; j < i; ++j) { |
| int a = tokens[j]; |
| int x = entry + j + 1; |
| int y = entry; |
| add_pop(a, x, a, y); |
| } |
| |
| int halt_idx = add_halt(S, 0); |
| |
| if (prev_halt != 0) { |
| prog[prev_halt - 1].y = entry; |
| } |
| prev_halt = halt_idx; |
| segments.push_back({entry, halt_idx}); |
| }; |
|
|
| for (int i = 1; i <= 30; ++i) { |
| if ((T >> i) & 1LL) { |
| add_block_i(i); |
| } |
| } |
|
|
| |
| if (H == 1) { |
| int entry = (int)prog.size() + 1; |
| int halt_idx = add_halt(S, 0); |
| if (prev_halt != 0) { |
| prog[prev_halt - 1].y = entry; |
| } |
| prev_halt = halt_idx; |
| } |
|
|
| |
| int cleanup_start = (int)prog.size() + 1; |
| int c1 = add_pop(S, cleanup_start, S, cleanup_start + 1); |
| int c2 = add_pop(S, cleanup_start + 2, S, cleanup_start + 1); |
| int c3 = add_halt(S, cleanup_start + 2); |
|
|
| |
| if (!segments.empty() || H == 1) { |
| |
| prog[prev_halt - 1].y = cleanup_start; |
| |
| int first_entry = segments.empty() ? ((int)prog.size() >= cleanup_start ? cleanup_start - 2 : cleanup_start) : segments.front().first; |
| prog[init_idx - 1].x = first_entry; |
| prog[init_idx - 1].y = first_entry; |
| } else { |
| |
| prog[init_idx - 1].x = cleanup_start; |
| prog[init_idx - 1].y = cleanup_start; |
| } |
|
|
| |
| cout << (int)prog.size() << "\n"; |
| for (int i = 0; i < (int)prog.size(); ++i) { |
| if (prog[i].type == 0) { |
| cout << "POP " << prog[i].a << " GOTO " << prog[i].x |
| << " PUSH " << prog[i].b << " GOTO " << prog[i].y << "\n"; |
| } else { |
| cout << "HALT PUSH " << prog[i].b << " GOTO " << prog[i].y << "\n"; |
| } |
| } |
| return 0; |
| } |