Advertisement
Nicba1010

Day5v3

Dec 5th, 2020
817
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.16 KB | None | 0 0
  1. /**
  2.  * Copyright (c) 2020 Nicba1010 All rights reserved.
  3.  */
  4.  
  5. #include <sys/stat.h>
  6.  
  7. #include <cstdint>
  8. #include <ctgmath>
  9.  
  10. #include <fstream>
  11. #include <iostream>
  12.  
  13. /**
  14.  * Use the retarded approach of loading everything into memory.
  15.  */
  16. #define OVERDRIVE 1
  17.  
  18. static constexpr const char* input = "../day5_bigboi3.txt";
  19.  
  20. #if 0
  21. /**
  22.  * @brief Finds the desired value by searching through the lower and upper bound by splitting the
  23.  *        search area in half every instruction.
  24.  *
  25.  * @details Finds the desired value by searching through the lower and upper bound by splitting the
  26.  *          search area in half every instruction according to the following rules.<br>
  27.  *          If the lowerBoundDesignator is detected it keeps the lower bound, but subtracts from
  28.  *          the upper bound using the following equation.
  29.  *          @code upperBound -= (upperBound - lowerBound + 1) / 2 @endcode
  30.  *          If the upperBoundDesignator is detected it keeps the upper bound, but adds to the
  31.  *          lower bound using the following equation.
  32.  *          @code lowerBound += (upperBound - lowerBound + 1) / 2 @endcode
  33.  *
  34.  * @param lowerBound           Lower bound to start searching from.
  35.  * @param upperBound           Upper bound to start searching from.
  36.  * @param instructions         A input of characters either lowerBoundDesignator or
  37.  *                             upperBoundDesignator.
  38.  * @param lowerBoundDesignator Lower bound instruction character.
  39.  * @param upperBoundDesignator Upper bound instruction character.
  40.  *
  41.  * @throws std::runtime_error in case of an invalid instruction input or
  42.  *         lowerBoundDesignator/upperBoundDesignator.
  43.  *
  44.  * @return The found value.
  45.  */
  46. static uint64_t splitFind(uint64_t           lowerBound,
  47.                           uint64_t           upperBound,
  48.                           const std::input& instructions,
  49.                           const char         lowerBoundDesignator,
  50.                           const char         upperBoundDesignator)
  51. {
  52.     for (uint64_t iChar = 0; iChar < instructions.size(); ++iChar) {
  53.         char c = instructions.c_str()[iChar];
  54.  
  55.         if (c == lowerBoundDesignator) {
  56.             lowerBound = lowerBound;
  57.             upperBound -= (upperBound - lowerBound + 1) / 2;
  58.         } else if (c == upperBoundDesignator) {
  59.             lowerBound += (upperBound - lowerBound + 1) / 2;
  60.             upperBound = upperBound;
  61.         } else {
  62.             throw std::runtime_error("Either invalid instruction input, or "
  63.                                      "lowerBoundDesignator/upperBoundDesignator!");
  64.         }
  65.     }
  66.  
  67.     return lowerBound == upperBound ? lowerBound
  68.                                     : throw std::runtime_error("Lower and upper bound do not "
  69.                                                                "match, possibly wrong instruction "
  70.                                                                "input!");
  71. }
  72. #endif
  73.  
  74. /**
  75.  * @brief More optimized version of splitFind.
  76.  *
  77.  * @param instructions         Instructions char*.
  78.  * @param instructionsSize     Instructions char* size.
  79.  * @param upperBoundDesignator Upper bound selector character.
  80.  *
  81.  * @return Calculated value.
  82.  */
  83. inline static uint64_t splitFindBetter(const char*    instructions,
  84.                                        const uint64_t instructionsSize,
  85.                                        const char     upperBoundDesignator)
  86. {
  87.     uint64_t result = 0;
  88.     for (uint64_t iChar = 0; iChar < instructionsSize; ++iChar) {
  89.         result = ((result << 1) | (instructions[iChar] == upperBoundDesignator));
  90.     }
  91.     return result;
  92. }
  93.  
  94. /**
  95.  * @brief Calculates the seat ID according to the following equation.
  96.  *        @code row * rowSeatIdMultiplier + col @endcode
  97.  *
  98.  * @param row                 Seat row.
  99.  * @param col                 Seat column.
  100.  * @param rowSeatIdMultiplier Seat row multipliers.
  101.  *
  102.  * @return The calculated seat ID
  103.  */
  104. inline static uint64_t calculateSeatId(uint64_t row, uint64_t col, uint64_t rowSeatIdMultiplier)
  105. {
  106.     return (row << rowSeatIdMultiplier) + col;
  107. }
  108.  
  109. int main()
  110. {
  111. #if OVERDRIVE
  112.     struct stat stat_buf {};
  113.     stat(input, &stat_buf);
  114. #endif
  115.  
  116.     std::ifstream file(input);
  117.  
  118.     std::string line0;
  119.     getline(file, line0);
  120.     file.seekg(0, std::ios::beg);
  121.  
  122.     uint64_t rowCharCount =
  123.         static_cast<uint64_t>(std::max(line0.find_last_of('F'), line0.find_last_of('B'))) + 1;
  124.     uint64_t colCharCount = line0.size() - rowCharCount;
  125.  
  126.     const uint64_t rowSize  = std::pow(2, rowCharCount);
  127.     const uint64_t colSize  = std::pow(2, colCharCount);
  128.     auto           seatGrid = new bool*[rowSize];
  129.     for (int iRow = 0; iRow < rowSize; ++iRow) {
  130.         seatGrid[iRow] = new bool[colSize];
  131.     }
  132.     uint64_t seatIdMax = 0;
  133.  
  134. #if OVERDRIVE
  135.     char* data = static_cast<char*>(malloc(stat_buf.st_size));
  136.     file.read(data, stat_buf.st_size);
  137.  
  138.     uint64_t startRowIndex = 0;
  139.     while (startRowIndex < stat_buf.st_size) {
  140.         uint64_t row = splitFindBetter(data + startRowIndex, rowCharCount, 'B');
  141.         uint64_t col = splitFindBetter(data + startRowIndex + rowCharCount, colCharCount, 'R');
  142. #else
  143.     char instructions[rowCharCount + colCharCount + 1];
  144.     while (file.read(reinterpret_cast<char*>(instructions), rowCharCount + colCharCount + 1)) {
  145.         uint64_t row = splitFindBetter(instructions, rowCharCount, 'B');
  146.         uint64_t col = splitFindBetter(instructions + rowCharCount, colCharCount, 'R');
  147. #endif
  148.  
  149.         uint64_t seatId = calculateSeatId(row, col, colCharCount);
  150.  
  151.         seatIdMax          = std::max(seatIdMax, seatId);
  152.         seatGrid[row][col] = true;
  153.  
  154.         startRowIndex += rowCharCount + colCharCount + 1;
  155.     }
  156.  
  157.     std::cout << "Highest seat ID is: " << seatIdMax << std::endl;
  158.     for (uint64_t iRow = 1; iRow < rowSize - 1; ++iRow) {
  159.         for (uint64_t iCol = 1; iCol < colSize - 1; ++iCol) {
  160.             if (!seatGrid[iRow][iCol] && seatGrid[iRow][iCol - 1] && seatGrid[iRow][iCol + 1]) {
  161.                 std::cout << "Your seat ID is: " << calculateSeatId(iRow, iCol, colSize)
  162.                           << std::endl;
  163.                 return 0;
  164.             }
  165.         }
  166.     }
  167. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement