davehill

AoC 2022 day 22

Dec 22nd, 2022
703
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.56 KB | None | 0 0
  1. #include "2022_utils.h"
  2. using namespace std;
  3.  
  4. namespace {
  5.   struct V {
  6.     int x, y;
  7.   };
  8.  
  9.   auto part1() {
  10.     auto inx = load_strings("2022/2022_day22_input.txt");
  11.  
  12.     vector<string> g(inx.begin(), inx.begin() + 12);
  13.     int instr_start = 13;
  14.  
  15.     // Real problem.
  16.     if (inx.size() > 30) {
  17.       instr_start = 201;
  18.       g.assign(inx.begin(), inx.begin() + 200);
  19.     }
  20.     auto g2 = g;
  21.  
  22.     // Make all lines same length.
  23.     int max_length = 0;
  24.     for (auto& s : g) {
  25.       max_length = max(max_length, (int)s.size());
  26.     }
  27.     for (auto& s : g) {
  28.       s.resize(max_length, ' ');
  29.     }
  30.  
  31.     auto next = [&](V p, int facing, char search, int max = 999999) {
  32.       p.y = p.y % g.size();
  33.       p.x = p.x % g[p.y].size();
  34.       while (g[p.y][p.x] != search && max-- > 0) {
  35.         if (g[p.y][p.x] != ' ') {
  36.           g2[p.y][p.x] = ">v<^"[facing];
  37.         }
  38.  
  39.         switch (facing) {
  40.         case 0: ++p.x; break;
  41.         case 1: ++p.y; break;
  42.         case 2: --p.x; break;
  43.         case 3: --p.y; break;
  44.         };
  45.  
  46.         p.y = (p.y + g.size()) % g.size();
  47.         p.x = (p.x + g[p.y].size()) % g[p.y].size();
  48.         if (g[p.y][p.x] == ' ') ++max;
  49.       }
  50.       return p;
  51.     };
  52.  
  53.     // facing = 0 east, 1 south, 2 west, 3 north
  54.     int facing = 0;
  55.     V p = next({0, 0}, facing, '.');
  56.  
  57.     for (int i = instr_start; i < inx.size(); ++i) {
  58.       string& instr = inx[i];
  59.       int amount = 0;
  60.       if (sscanf_s(instr.c_str(), "%d", &amount)) {
  61.         p = next(p, facing, '#', amount);
  62.  
  63.         if (g[p.y][p.x] == '#') {
  64.           p = next(p, (facing + 2) % 4, '.', 1); // go back to last space.
  65.         }
  66.       }
  67.       else if (instr == "L") {
  68.         facing = (facing + 3) % 4;
  69.       }
  70.       else if (instr == "R") {
  71.         facing = (facing + 1) % 4;
  72.       }
  73.     }
  74.  
  75.     return (1000 * (p.y + 1)) + (4 * (p.x + 1)) + facing;
  76.   }
  77.  
  78.   auto part2() {
  79.     auto inx = load_strings("2022/2022_day22_input.txt");
  80.  
  81.     int instr_start = 201;
  82.     vector<string> grid(inx.begin(), inx.begin() + 200);
  83.     auto visualization_grid = grid;
  84.  
  85.     // Make all input lines same length to make indexing easier.
  86.     int max_length = 0;
  87.     for (auto& s : grid) {
  88.       max_length = max(max_length, (int)s.size());
  89.     }
  90.     for (auto& s : grid) {
  91.       s.resize(max_length, ' ');
  92.     }
  93.  
  94.     struct Edge {
  95.       int min_x = -1;
  96.       int max_x = -1;
  97.       int min_y = -1;
  98.       int max_y = -1;
  99.       function<V(V)> warp;
  100.       int new_facing = -1;
  101.     };
  102.  
  103.     vector<vector<Edge>> edges = {
  104.       // Right-facing edges.
  105.       {
  106.         // R0 (-> R2)
  107.         {
  108.           .min_x = 149,
  109.           .max_x = 149,
  110.           .min_y = 0,
  111.           .max_y = 49,
  112.           .warp = [](V p) { return V{ 99, 149 - p.y }; },
  113.           .new_facing = 2,
  114.         },
  115.         // R1 (-> D1)
  116.         {
  117.           .min_x = 99,
  118.           .max_x = 99,
  119.           .min_y = 50,
  120.           .max_y = 99,
  121.           .warp = [](V p) { return V{ p.y + 50, 49 }; },
  122.           .new_facing = 3,
  123.         },
  124.         // R2 (-> R0)
  125.         {
  126.           .min_x = 99,
  127.           .max_x = 99,
  128.           .min_y = 100,
  129.           .max_y = 149,
  130.           .warp = [](V p) { return V{ 149, 149 - p.y }; },
  131.           .new_facing = 2,
  132.         },
  133.         // R3 (-> D2)
  134.         {
  135.           .min_x = 49,
  136.           .max_x = 49,
  137.           .min_y = 150,
  138.           .max_y = 199,
  139.           .warp = [](V p) { return V{ p.y - 100, 149 }; },
  140.           .new_facing = 3,
  141.         },
  142.       },
  143.       // Down-facing edges
  144.       {
  145.         // D1 (-> R1)
  146.         {
  147.           .min_x = 100,
  148.           .max_x = 149,
  149.           .min_y = 49,
  150.           .max_y = 49,
  151.           .warp = [](V p) { return V{ 99, p.x - 50 }; },
  152.           .new_facing = 2,
  153.         },
  154.         // D2 (-> R3)
  155.         {
  156.           .min_x = 50,
  157.           .max_x = 99,
  158.           .min_y = 149,
  159.           .max_y = 149,
  160.           .warp = [](V p) { return V{ 49, p.x + 100 }; },
  161.           .new_facing = 2,
  162.         },
  163.         // D3 (-> U3)
  164.         {
  165.           .min_x = 0,
  166.           .max_x = 49,
  167.           .min_y = 199,
  168.           .max_y = 199,
  169.           .warp = [](V p) { return V{ p.x + 100, 0 }; },
  170.           .new_facing = 1,
  171.         },
  172.       },
  173.       // Left-facing edges.
  174.       {
  175.         // L1 (-> L3)
  176.         {
  177.           .min_x = 50,
  178.           .max_x = 50,
  179.           .min_y = 0,
  180.           .max_y = 49,
  181.           .warp = [](V p) { return V{ 0, 149 - p.y }; },
  182.           .new_facing = 0,
  183.         },
  184.         // L2 (-> U1)
  185.         {
  186.           .min_x = 50,
  187.           .max_x = 50,
  188.           .min_y = 50,
  189.           .max_y = 99,
  190.           .warp = [](V p) { return V{ p.y - 50, 100 }; },
  191.           .new_facing = 1,
  192.         },
  193.         // L3 (-> L1)
  194.         {
  195.           .min_x = 0,
  196.           .max_x = 0,
  197.           .min_y = 100,
  198.           .max_y = 149,
  199.           .warp = [](V p) { return V{ 50, 149 - p.y }; },
  200.           .new_facing = 0,
  201.         },
  202.         // L4 (-> U2)
  203.         {
  204.           .min_x = 0,
  205.           .max_x = 0,
  206.           .min_y = 150,
  207.           .max_y = 199,
  208.           .warp = [](V p) { return V{ p.y - 100, 0 }; },
  209.           .new_facing = 1,
  210.         },
  211.       },
  212.       // Up-facing edges
  213.       {
  214.         // U1 (-> L2)
  215.         {
  216.           .min_x = 0,
  217.           .max_x = 49,
  218.           .min_y = 100,
  219.           .max_y = 100,
  220.           .warp = [](V p) { return V{ 50, p.x + 50 }; },
  221.           .new_facing = 0,
  222.         },
  223.         // U2 (-> L4)
  224.         {
  225.           .min_x = 50,
  226.           .max_x = 99,
  227.           .min_y = 0,
  228.           .max_y = 0,
  229.           .warp = [](V p) { return V{ 0, p.x + 100 }; },
  230.           .new_facing = 0,
  231.         },
  232.         // U3 (-> D3)
  233.         {
  234.           .min_x = 100,
  235.           .max_x = 149,
  236.           .min_y = 0,
  237.           .max_y = 0,
  238.           .warp = [](V p) { return V{ p.x + 50, 49 }; },
  239.           .new_facing = 3,
  240.         },
  241.       }
  242.     };
  243.  
  244.     auto next = [&](V p, int& facing, char search, int max) {
  245.       p.y = p.y % grid.size();
  246.       p.x = p.x % grid[p.y].size();
  247.       while (grid[p.y][p.x] != search && max-- > 0) {
  248.         if (grid[p.y][p.x] != ' ') {
  249.           visualization_grid[p.y][p.x] = ">v<^"[facing];
  250.         }
  251.  
  252.         // Test going over and edge.
  253.         bool over_edge = false;
  254.         for (Edge& edge : edges[facing]) {
  255.           if (p.x >= edge.min_x && p.x <= edge.max_x
  256.             && p.y >= edge.min_y && p.y <= edge.max_y) {
  257.             p = edge.warp(p);
  258.             facing = edge.new_facing;
  259.             over_edge = true;
  260.             break;
  261.           }
  262.         }
  263.  
  264.         // Regular movement.
  265.         if (!over_edge) {
  266.           switch (facing) {
  267.           case 0: ++p.x; break;
  268.           case 1: ++p.y; break;
  269.           case 2: --p.x; break;
  270.           case 3: --p.y; break;
  271.           };
  272.         }
  273.  
  274.         p.y = (p.y + grid.size()) % grid.size();
  275.         p.x = (p.x + grid[p.y].size()) % grid[p.y].size();
  276.         if (grid[p.y][p.x] == ' ') ++max;
  277.       }
  278.       return V{ p.x, p.y };
  279.     };
  280.  
  281.     // facing: 0 east, 1 south, 2 west, 3 north
  282.     int facing = 0;
  283.     V p = next({ 0, 0 }, facing, '.', 9999);
  284.  
  285.     int i_max = inx.size();
  286.     for (int i = instr_start; i < i_max; ++i) {
  287.       string& instr = inx[i];
  288.       int amount = 0;
  289.       if (sscanf_s(instr.c_str(), "%d", &amount)) {
  290.         p = next(p, facing, '#', amount);
  291.  
  292.         // If we hit a wall turn back, move a square, then turn again.
  293.         if (grid[p.y][p.x] == '#') {
  294.           facing = (facing + 2) % 4;
  295.           p = next(p, facing, '.', 1);
  296.           facing = (facing + 2) % 4;
  297.         }
  298.       }
  299.       else if (instr == "L") {
  300.         facing = (facing + 3) % 4;
  301.       }
  302.       else if (instr == "R") {
  303.         facing = (facing + 1) % 4;
  304.       }
  305.     }
  306.  
  307. /*
  308.     struct Annotation {
  309.       char c;
  310.       int x;
  311.       int y;
  312.       int facing;
  313.     };
  314.     vector<Annotation> an = {
  315.       { 'R', 75, 2, 0 },
  316.       { 'L', 75, 4, 2 },
  317.       { 'D', 6, 25, 1 },
  318.       { 'U', 8, 25, 3 },
  319.       { '1', 75, 60, 0 },
  320.       { '2', 75, 62, 2 },
  321.       { '3', 64, 70, 1 },
  322.       { '4', 66, 70, 3 },
  323.     };
  324.  
  325.     for (auto& a : an) {
  326.       V p{ a.x, a.y };
  327.       visualization_grid[p.y][p.x] = a.c;
  328.       for (int i = 0; i < 1000; ++i) {
  329.         p = next(p, a.facing, '-', 1);
  330.         visualization_grid[p.y][p.x] = a.c;
  331.       }
  332.     }
  333.  
  334.     printf("\n");
  335.     for (auto& s : visualization_grid) {
  336.       printf("%s\n", s.c_str());
  337.     }
  338. */
  339.  
  340.     return (1000 * (p.y + 1)) + (4 * (p.x + 1)) + facing;
  341.   }
  342. }
  343.  
  344. namespace y2022 {
  345.   void day22() {
  346.     cout << "part 1: " << part1() << "\n";
  347.     cout << "part 2: " << part2() << "\n";
  348.   }
  349. }
  350.  
Advertisement
Add Comment
Please, Sign In to add comment