Advertisement
Guest User

AOC 2024-18

a guest
Dec 24th, 2024
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.07 KB | Source Code | 0 0
  1. #include <algorithm>
  2. #include <climits>
  3. #include <cmath>
  4. #include <cstdlib>
  5. #include <deque>
  6. #include <iostream>
  7. #include <fstream>
  8. #include <queue>
  9. #include <string>
  10. #include <vector>
  11. #include <sstream>
  12.  
  13. using namespace std;
  14.  
  15. #define MAP_SIZE 70
  16. #define NUM_BYTES_TO_SIM 1024
  17.  
  18. struct coords {
  19.     int x;
  20.     int y;
  21.     int score;
  22.  
  23.     bool operator>(const coords& other) const {
  24.         return score > other.score;
  25.     }
  26.  
  27.     bool operator==(const coords& other) const {
  28.         return x == other.x && y == other.y;
  29.     }
  30. };
  31.  
  32.  
  33. vector<string> split (const string &s, char delim) {
  34.     vector<string> result;
  35.     stringstream ss (s);
  36.     string item;
  37.  
  38.     while (getline (ss, item, delim)) {
  39.         result.push_back (item);
  40.     }
  41.  
  42.     return result;
  43. }
  44.  
  45. vector<string> readFile(string path) {
  46.     ifstream file(path);
  47.     vector<string> lines;
  48.     string line;
  49.  
  50.     if (file.is_open()) {
  51.         while (getline(file, line)) {
  52.             lines.push_back(line);
  53.         }
  54.         file.close();
  55.     } else {
  56.         cout << "Unable to open file" << endl;
  57.     }
  58.  
  59.     return lines;
  60. }
  61.  
  62. vector<coords> parseBytes(vector<string> input) {
  63.     vector<coords> fallingBytes;
  64.     for (string byte : input) {
  65.         vector<string> coord = split(byte, ',');
  66.         fallingBytes.push_back({stoi(coord[0]), stoi(coord[1])});
  67.     }
  68.     return fallingBytes;
  69. }
  70.  
  71. vector<string> createEmptyMemorySpace() {
  72.     vector<string> memorySpace;
  73.     string row;
  74.     for (int i = 0; i <= MAP_SIZE; i++) {
  75.         row.push_back('.');
  76.     }
  77.     for (int j = 0; j <= MAP_SIZE; j++) {
  78.         memorySpace.push_back(row);
  79.     }
  80.     return memorySpace;
  81. }
  82.  
  83. void simulateFallingBytes(vector<string> *memorySpace, vector<coords> *fallingBytes, int numToSimulate) {
  84.     for (int i = 0; i < numToSimulate; i++) {
  85.         coords byte = fallingBytes->at(i);
  86.         memorySpace->at(byte.y).at(byte.x) = '#';
  87.     }
  88. }
  89.  
  90. bool isInMap(coords *next, vector<string> *map) {
  91.     if (next->x >= 0 && next->x <= MAP_SIZE && next->y >= 0 && next->y <= MAP_SIZE) {
  92.         return true;
  93.     }
  94.     else return false;
  95. }
  96. bool isBlocked(coords *next, vector<string> *map) {
  97.     if (map->at(next->y).at(next->x) == '#') return true;
  98.     else return false;
  99. }
  100. bool isVisited(coords next, vector<coords> *visited) {
  101.     for (int i = 0; i < visited->size(); i++) {
  102.         if (next == visited->at(i)) {
  103.             return true;
  104.         }
  105.     }
  106.     return false;
  107. }
  108. vector<coords> getCurrentOptions(coords currentCoord, vector<coords> visited, vector<string> *map) {
  109.     vector<coords> currentOptions;
  110.     coords north = {currentCoord.x, currentCoord.y - 1, currentCoord.score + 1};
  111.     coords east = {currentCoord.x + 1, currentCoord.y, currentCoord.score + 1};
  112.     coords south = {currentCoord.x, currentCoord.y + 1, currentCoord.score + 1};
  113.     coords west = {currentCoord.x - 1, currentCoord.y, currentCoord.score + 1};
  114.  
  115.     if (isInMap(&north, map) && !isBlocked(&north, map) && !isVisited(north, &visited)) {
  116.         currentOptions.push_back(north);
  117.     }
  118.     if (isInMap(&east, map) && !isBlocked(&east, map) && !isVisited(east, &visited)) {
  119.         currentOptions.push_back(east);
  120.     }
  121.     if (isInMap(&south, map) && !isBlocked(&south, map) && !isVisited(south, &visited)) {
  122.         currentOptions.push_back(south);
  123.     }
  124.     if (isInMap(&west, map) && !isBlocked(&west, map) && !isVisited(west, &visited)) {
  125.         currentOptions.push_back(west);
  126.     }
  127.  
  128.     return currentOptions;
  129. }
  130.  
  131. int findShortestPath(vector<string> *memorySpace, coords start, coords end) {
  132.     queue<coords> toExplore;
  133.     vector<coords> visited;
  134.     toExplore.push(start);
  135.  
  136.     while (!toExplore.empty()) {
  137.         coords current = toExplore.front();
  138.         toExplore.pop();
  139.  
  140.         //memorySpace->at(current.y).at(current.x) = '0';
  141.  
  142.         if (current.x == end.x && current.y == end.y) {
  143.             return current.score;
  144.         }
  145.  
  146.         visited.push_back(current);
  147.         vector<coords> currentOptions = getCurrentOptions(current, visited, memorySpace);
  148.  
  149.         for (coords next : currentOptions) {
  150.             bool alreadyQueued = false;
  151.             queue<coords> tempQueue = toExplore;
  152.             while (!tempQueue.empty()) {
  153.                 if (tempQueue.front() == next) {
  154.                     alreadyQueued = true;
  155.                     break;
  156.                 }
  157.                 tempQueue.pop();
  158.             }
  159.  
  160.             if (!alreadyQueued && find(visited.begin(), visited.end(), next) == visited.end()) {
  161.                 toExplore.push(next);
  162.             }
  163.         }
  164.     }
  165.     return -1;
  166. }
  167.  
  168. string binarySearchCutOff(vector<coords> fallingBytes) {
  169.     coords start = {0, 0};
  170.     coords end = {MAP_SIZE, MAP_SIZE};
  171.     vector<string> memorySpace = createEmptyMemorySpace();
  172.  
  173.     int low = 0;
  174.     int high = fallingBytes.size()-1;
  175.     int mid;
  176.  
  177.     while (low <= high) {
  178.         mid = low + (high - low) / 2;
  179.  
  180.         vector<string> tempMap = memorySpace;
  181.         simulateFallingBytes(&tempMap, &fallingBytes, mid);
  182.         int shortestPath = findShortestPath(&tempMap, start, end);
  183.  
  184.         if (shortestPath == -1) {
  185.             high = mid - 1;
  186.         }
  187.         else {
  188.             low = mid + 1;
  189.         }
  190.     }
  191.     coords cutoff = fallingBytes[mid - 1];
  192.     return "" + to_string(cutoff.x) + "," + to_string(cutoff.y);
  193.  
  194. }
  195.  
  196. int part1(vector<coords> fallingBytes) {
  197.     coords start = {0, 0};
  198.     coords end = {MAP_SIZE, MAP_SIZE};
  199.     vector<string> memorySpace = createEmptyMemorySpace();
  200.  
  201.     simulateFallingBytes(&memorySpace, &fallingBytes, NUM_BYTES_TO_SIM);
  202.     int shortestPath = findShortestPath(&memorySpace, start, end);
  203.  
  204.     cout << "Part 1 result: " << shortestPath << endl;
  205.  
  206.     return 0;
  207. }
  208.  
  209. int part2(vector<coords> fallingBytes) {
  210.     string cutoff = binarySearchCutOff(fallingBytes);
  211.  
  212.     cout << "Part 2 result: " << cutoff << endl;
  213.  
  214.     return 0;
  215. }
  216.  
  217. int main() {
  218.     vector<string> input = readFile("day18_input.txt");
  219.     vector<coords> fallingBytes = parseBytes(input);
  220.     part1(fallingBytes);
  221.     part2(fallingBytes);
  222.  
  223.     return 0;
  224. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement