Advertisement
adrien1018

Untitled

Feb 18th, 2025
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.47 KB | None | 0 0
  1. #include <unordered_map>
  2. #include <cstdio>
  3. #include <string>
  4. #include <vector>
  5. #include <cstring>
  6. #include <utility>
  7.  
  8. using std::pair;
  9. using std::unordered_map;
  10. using std::string;
  11. using std::vector;
  12.  
  13. const char code_path[20] = "sub_1.txt"; //code file
  14. const char grid_path[20] = "grid_1.txt"; //grid file
  15. const uint32_t gridN = 256; // grid size
  16. bool print_grid = true; //print final grid
  17.  
  18. char code[1048571];
  19.  
  20. struct error {
  21.     error() {}
  22.     error(uint32_t a, uint32_t b, string c) : error_no(a), line(b), str(c) {}
  23.     uint32_t error_no, line;
  24.     string str;
  25. };
  26.  
  27. const uint32_t maxpeb = 15;
  28. uint8_t grid[gridN][gridN], grid_init[gridN][gridN];
  29.  
  30. uint32_t lines, tline;
  31. unordered_map<string, uint32_t> tag; //tag, line
  32. vector<pair<uint32_t, string>> totag; //line, tag
  33. vector<pair<uint32_t, uint32_t>> program; //mode, (toline)
  34.     // 0: left, 1: right, 2: move, 3: get, 4: put, 5: halt, 6: jump, 7: border, 8: pebble
  35.  
  36. void initialize() {
  37.     freopen(grid_path, "r", stdin);
  38.     memset(grid, 0x00, gridN * gridN);
  39.     uint32_t x, y, t;
  40.     while (~scanf("%u%u%u", &x, &y, &t)) {
  41.         if (x >= gridN || x >= gridN || t > maxpeb) throw error(0, 0, ""); //invalid input
  42.         grid[x][y] = t;
  43.     }
  44.     memcpy(grid_init, grid, gridN * gridN);
  45.  
  46.     lines = tline = 0;
  47.  
  48.     FILE* pFile = fopen(code_path, "r");
  49.     size_t p = fread(code, 1, 1048571, pFile);
  50.     code[p] = 0;
  51. }
  52.  
  53. inline bool isg(char p) {
  54.     return (p >= 'A' && p <= 'Z' || p >= 'a' && p <= 'z' || p >= '0' && p <= '9' || p == '_');
  55. }
  56.  
  57. void compile_line(char* p, char* end) {
  58.     tline++;
  59.     string str[2];
  60.     bool flag = false;
  61.     int8_t cr = 0;
  62.     while (p != end) {
  63.         if (isg(*p)) {
  64.             if (cr == 2 || flag) throw error(1, tline, ""); //word after tag or two words
  65.             str[cr] += *p;
  66.             if (str[cr].size() > 128) throw error(2, tline, ""); //too long
  67.         }
  68.         else if (*p == ' ') {
  69.             if (str[cr].size()) cr++;
  70.         }
  71.         else if (*p == '#' || *p == '\n' || *p == '\r' || *p == '\0') {
  72.             if (str[cr].size()) cr++;
  73.             break;
  74.         }
  75.         else if (*p == ':') {
  76.             if (!str[cr].size()) throw error(3, tline, ""); //empty tag
  77.             cr++, flag = true;
  78.         }
  79.         else throw error(4, tline, string(1, *p)); //invalid character
  80.         p++;
  81.     }
  82.  
  83.     if (flag) {
  84.         if (tag.count(str[0])) throw error(5, tline, str[0]); //same-name tag
  85.         tag[str[0]] = lines--;
  86.     }
  87.     else if (str[0] == "left" && !str[1].size()) program.push_back(pair<uint32_t, uint32_t>(0, 0));
  88.     else if (str[0] == "right" && !str[1].size()) program.push_back(pair<uint32_t, uint32_t>(1, 0));
  89.     else if (str[0] == "move" && !str[1].size()) program.push_back(pair<uint32_t, uint32_t>(2, 0));
  90.     else if (str[0] == "get" && !str[1].size()) program.push_back(pair<uint32_t, uint32_t>(3, 0));
  91.     else if (str[0] == "put" && !str[1].size()) program.push_back(pair<uint32_t, uint32_t>(4, 0));
  92.     else if (str[0] == "halt" && !str[1].size()) program.push_back(pair<uint32_t, uint32_t>(5, 0));
  93.     else if (str[0] == "jump" && str[1].size()) {
  94.         program.push_back(pair<uint32_t, uint32_t>(6, 0));
  95.         totag.push_back(pair<uint32_t, string>(lines, str[1]));
  96.     }
  97.     else if (str[0] == "border" && str[1].size()) {
  98.         program.push_back(pair<uint32_t, uint32_t>(7, 0));
  99.         totag.push_back(pair<uint32_t, string>(lines, str[1]));
  100.     }
  101.     else if (str[0] == "pebble" && str[1].size()) {
  102.         program.push_back(pair<uint32_t, uint32_t>(8, 0));
  103.         totag.push_back(pair<uint32_t, string>(lines, str[1]));
  104.     }
  105.     else if (!str[0].size()) lines--;
  106.     else throw error(6, tline, str[0] + ' ' + str[1]); //invalid command
  107.     lines++;
  108. }
  109.  
  110. void compile(char* p) {
  111.     char *prev = p, *now = p;
  112.     while (*now) {
  113.         if (*now == '\n') {
  114.             compile_line(prev, now + 1);
  115.             prev = now + 1;
  116.         }
  117.         now++;
  118.     }
  119.     compile_line(prev, now + 1);
  120.  
  121.     unordered_map<string, uint32_t>::iterator it;
  122.     for (auto& i : totag) {
  123.         if ((it = tag.find(i.second)) != tag.end()) program[i.first].second = it->second;
  124.         else throw error(7, 0, i.second); //undefined tag
  125.     }
  126. }
  127.  
  128. uint32_t tx, ty, dir;
  129. uint32_t nowline;
  130. uint32_t steps;
  131. const int32_t dy[4] = {0, -1, 0, 1}; //left++
  132. const int32_t dx[4] = {-1, 0, 1, 0};
  133.  
  134. inline bool face_border() {
  135.     return (!ty && dir == 1 || !tx && !dir || ty == 255 && dir == 3 || tx == 255 && dir == 2);
  136. }
  137.  
  138. void execute() {
  139.     nowline = steps = tx = ty = dir = 0;
  140.     bool cont = true;
  141.     while (cont && nowline < lines) {
  142.         steps++;
  143.         switch (program[nowline].first) {
  144.             case 0: dir = (dir + 1) & 3; break;
  145.             case 1: dir = (dir + 3) & 3; break;
  146.             case 2: if (!face_border()) tx += dx[dir], ty += dy[dir]; break;
  147.             case 3: if (grid[tx][ty]) grid[tx][ty]--; break;
  148.             case 4: if (grid[tx][ty] != 15) grid[tx][ty]++; break;
  149.             case 5: cont = false; break;
  150.             case 6: nowline = program[nowline].second - 1; break;
  151.             case 7: if (face_border()) nowline = program[nowline].second - 1; break;
  152.             case 8: if (grid[tx][ty]) nowline = program[nowline].second - 1;
  153.         }
  154.         nowline++;
  155.     }
  156. }
  157.  
  158. int main()
  159. {
  160.     try {
  161.         initialize();
  162.         compile(code);
  163.         printf("Compiled. Commands: %u.\n", lines);
  164.         execute();
  165.         printf("Executed. Final position: (%u, %u). Steps: %u.\n", tx, ty, steps);
  166.         if (print_grid) {
  167.             for (uint32_t i = 0; i < gridN; i++) {
  168.                 for (uint32_t j = 0; j < gridN; j++) printf("%hhd ", grid[i][j]);
  169.                 putchar('\n');
  170.             }
  171.         }
  172.     }
  173.     catch (error e) {
  174.         puts("Complication error.");
  175.         switch (e.error_no) {
  176.             case 0: puts("Invalid grid input."); break;
  177.             case 1: printf("Line %u: Text after tag or too many arguments.", e.line); break;
  178.             case 2: printf("Line %u: Identifier is too long.", e.line); break;
  179.             case 3: printf("Line %u: Empty tag.", e.line); break;
  180.             case 4: printf("Line %u: Invalid character \'%s\'.", e.line, e.str.c_str()); break;
  181.             case 5: printf("Line %u: Redefinition of tag \'%s\'.", e.line, e.str.c_str()); break;
  182.             case 6: printf("Line %u: Invalid command \'%s\'.", e.line, e.str.c_str()); break;
  183.             case 7: printf("Undefined tag \'%s\'.", e.str.c_str());
  184.         }
  185.     }
  186. }
  187.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement