| #include <bits/stdc++.h> |
| using namespace std; |
|
|
| struct Instr { |
| enum Type { POP, HALT } type; |
| int a = 1, b = 1; |
| int x = 0, y = 0; |
| bool set = false; |
| }; |
|
|
| static const int NEVER = 1024; |
| static const int TEMP = 1023; |
|
|
| vector<Instr> prog; |
| int nextMarker = 1; |
|
|
| int newLabel() { |
| prog.push_back(Instr()); |
| return (int)prog.size() - 1; |
| } |
|
|
| void setPOP(int lbl, int a, int x, int b, int y) { |
| auto &ins = prog[lbl]; |
| ins.type = Instr::POP; |
| ins.a = a; |
| ins.x = x; |
| ins.b = b; |
| ins.y = y; |
| ins.set = true; |
| } |
|
|
| void setHALT(int lbl, int b, int y) { |
| auto &ins = prog[lbl]; |
| ins.type = Instr::HALT; |
| ins.b = b; |
| ins.y = y; |
| ins.set = true; |
| } |
|
|
| struct Proc { |
| int m0, m1; |
| int entry; |
| }; |
|
|
| Proc build(long long K, int cont0, int cont1) { |
| Proc p; |
| p.m0 = nextMarker++; |
| p.m1 = nextMarker++; |
|
|
| |
| int ret_check = newLabel(); |
|
|
| if (K <= 9) { |
| int m = (int)((K - 3) / 2); |
| if (m == 0) { |
| p.entry = ret_check; |
| } else { |
| p.entry = newLabel(); |
| int cur = p.entry; |
| for (int i = 0; i < m; i++) { |
| int popLbl = newLabel(); |
| setPOP(cur, NEVER, cur, TEMP, popLbl); |
| int nxt = (i == m - 1) ? ret_check : newLabel(); |
| setPOP(popLbl, TEMP, nxt, TEMP, nxt); |
| cur = nxt; |
| } |
| } |
| } else { |
| bool extra = (K % 4 == 1); |
| long long u = extra ? (K - 7) / 2 : (K - 5) / 2; |
|
|
| int entry = newLabel(); |
| int after1 = newLabel(); |
| int after2; |
| if (extra) after2 = newLabel(); |
| else after2 = ret_check; |
|
|
| |
| Proc sub = build(u, after1, after2); |
|
|
| |
| setPOP(entry, NEVER, entry, sub.m0, sub.entry); |
| setPOP(after1, NEVER, after1, sub.m1, sub.entry); |
|
|
| |
| if (extra) { |
| int popTemp = newLabel(); |
| setPOP(after2, NEVER, after2, TEMP, popTemp); |
| setPOP(popTemp, TEMP, ret_check, TEMP, ret_check); |
| } |
|
|
| p.entry = entry; |
| } |
|
|
| |
| int dummyPush = newLabel(); |
| int dummyPop = newLabel(); |
| int failPop = newLabel(); |
| int check1 = newLabel(); |
|
|
| setPOP(ret_check, p.m0, dummyPush, p.m0, failPop); |
| setPOP(dummyPush, NEVER, dummyPush, TEMP, dummyPop); |
| setPOP(dummyPop, TEMP, cont0, TEMP, cont0); |
| setPOP(failPop, p.m0, check1, p.m0, check1); |
| setPOP(check1, p.m1, cont1, p.m1, cont1); |
|
|
| return p; |
| } |
|
|
| int main() { |
| ios::sync_with_stdio(false); |
| cin.tie(nullptr); |
|
|
| long long k; |
| cin >> k; |
|
|
| if (k == 1) { |
| cout << 1 << "\n"; |
| cout << "HALT PUSH 1 GOTO 1\n"; |
| return 0; |
| } |
| if (k == 3) { |
| cout << 3 << "\n"; |
| cout << "POP 1 GOTO 1 PUSH 1 GOTO 2\n"; |
| cout << "POP 1 GOTO 3 PUSH 1 GOTO 2\n"; |
| cout << "HALT PUSH 1 GOTO 3\n"; |
| return 0; |
| } |
|
|
| |
| long long K = k - 2; |
|
|
| prog.clear(); |
| nextMarker = 1; |
|
|
| int start = newLabel(); |
| int haltLbl = newLabel(); |
| setHALT(haltLbl, 1, haltLbl); |
|
|
| Proc root = build(K, haltLbl, haltLbl); |
| setPOP(start, NEVER, start, root.m0, root.entry); |
|
|
| |
| for (int i = 0; i < (int)prog.size(); i++) { |
| if (!prog[i].set) { |
| |
| setHALT(i, 1, i); |
| } |
| } |
|
|
| int n = (int)prog.size(); |
| if (n > 512) { |
| |
| |
| n = 1; |
| prog.assign(1, Instr()); |
| setHALT(0, 1, 0); |
| } |
|
|
| cout << n << "\n"; |
| for (int i = 0; i < n; i++) { |
| const auto &ins = prog[i]; |
| if (ins.type == Instr::HALT) { |
| cout << "HALT PUSH " << ins.b << " GOTO " << (ins.y + 1) << "\n"; |
| } else { |
| cout << "POP " << ins.a << " GOTO " << (ins.x + 1) |
| << " PUSH " << ins.b << " GOTO " << (ins.y + 1) << "\n"; |
| } |
| } |
| return 0; |
| } |