Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * Copyright (c) 2020 Nicba1010 All rights reserved.
- */
- #include <sys/stat.h>
- #include <cstdint>
- #include <ctgmath>
- #include <fstream>
- #include <iostream>
- /**
- * Use the retarded approach of loading everything into memory.
- */
- #define OVERDRIVE 1
- static constexpr const char* input = "../day5_bigboi3.txt";
- #if 0
- /**
- * @brief Finds the desired value by searching through the lower and upper bound by splitting the
- * search area in half every instruction.
- *
- * @details Finds the desired value by searching through the lower and upper bound by splitting the
- * search area in half every instruction according to the following rules.<br>
- * If the lowerBoundDesignator is detected it keeps the lower bound, but subtracts from
- * the upper bound using the following equation.
- * @code upperBound -= (upperBound - lowerBound + 1) / 2 @endcode
- * If the upperBoundDesignator is detected it keeps the upper bound, but adds to the
- * lower bound using the following equation.
- * @code lowerBound += (upperBound - lowerBound + 1) / 2 @endcode
- *
- * @param lowerBound Lower bound to start searching from.
- * @param upperBound Upper bound to start searching from.
- * @param instructions A input of characters either lowerBoundDesignator or
- * upperBoundDesignator.
- * @param lowerBoundDesignator Lower bound instruction character.
- * @param upperBoundDesignator Upper bound instruction character.
- *
- * @throws std::runtime_error in case of an invalid instruction input or
- * lowerBoundDesignator/upperBoundDesignator.
- *
- * @return The found value.
- */
- static uint64_t splitFind(uint64_t lowerBound,
- uint64_t upperBound,
- const std::input& instructions,
- const char lowerBoundDesignator,
- const char upperBoundDesignator)
- {
- for (uint64_t iChar = 0; iChar < instructions.size(); ++iChar) {
- char c = instructions.c_str()[iChar];
- if (c == lowerBoundDesignator) {
- lowerBound = lowerBound;
- upperBound -= (upperBound - lowerBound + 1) / 2;
- } else if (c == upperBoundDesignator) {
- lowerBound += (upperBound - lowerBound + 1) / 2;
- upperBound = upperBound;
- } else {
- throw std::runtime_error("Either invalid instruction input, or "
- "lowerBoundDesignator/upperBoundDesignator!");
- }
- }
- return lowerBound == upperBound ? lowerBound
- : throw std::runtime_error("Lower and upper bound do not "
- "match, possibly wrong instruction "
- "input!");
- }
- #endif
- /**
- * @brief More optimized version of splitFind.
- *
- * @param instructions Instructions char*.
- * @param instructionsSize Instructions char* size.
- * @param upperBoundDesignator Upper bound selector character.
- *
- * @return Calculated value.
- */
- inline static uint64_t splitFindBetter(const char* instructions,
- const uint64_t instructionsSize,
- const char upperBoundDesignator)
- {
- uint64_t result = 0;
- for (uint64_t iChar = 0; iChar < instructionsSize; ++iChar) {
- result = ((result << 1) | (instructions[iChar] == upperBoundDesignator));
- }
- return result;
- }
- /**
- * @brief Calculates the seat ID according to the following equation.
- * @code row * rowSeatIdMultiplier + col @endcode
- *
- * @param row Seat row.
- * @param col Seat column.
- * @param rowSeatIdMultiplier Seat row multipliers.
- *
- * @return The calculated seat ID
- */
- inline static uint64_t calculateSeatId(uint64_t row, uint64_t col, uint64_t rowSeatIdMultiplier)
- {
- return (row << rowSeatIdMultiplier) + col;
- }
- int main()
- {
- #if OVERDRIVE
- struct stat stat_buf {};
- stat(input, &stat_buf);
- #endif
- std::ifstream file(input);
- std::string line0;
- getline(file, line0);
- file.seekg(0, std::ios::beg);
- uint64_t rowCharCount =
- static_cast<uint64_t>(std::max(line0.find_last_of('F'), line0.find_last_of('B'))) + 1;
- uint64_t colCharCount = line0.size() - rowCharCount;
- const uint64_t rowSize = std::pow(2, rowCharCount);
- const uint64_t colSize = std::pow(2, colCharCount);
- auto seatGrid = new bool*[rowSize];
- for (int iRow = 0; iRow < rowSize; ++iRow) {
- seatGrid[iRow] = new bool[colSize];
- }
- uint64_t seatIdMax = 0;
- #if OVERDRIVE
- char* data = static_cast<char*>(malloc(stat_buf.st_size));
- file.read(data, stat_buf.st_size);
- uint64_t startRowIndex = 0;
- while (startRowIndex < stat_buf.st_size) {
- uint64_t row = splitFindBetter(data + startRowIndex, rowCharCount, 'B');
- uint64_t col = splitFindBetter(data + startRowIndex + rowCharCount, colCharCount, 'R');
- #else
- char instructions[rowCharCount + colCharCount + 1];
- while (file.read(reinterpret_cast<char*>(instructions), rowCharCount + colCharCount + 1)) {
- uint64_t row = splitFindBetter(instructions, rowCharCount, 'B');
- uint64_t col = splitFindBetter(instructions + rowCharCount, colCharCount, 'R');
- #endif
- uint64_t seatId = calculateSeatId(row, col, colCharCount);
- seatIdMax = std::max(seatIdMax, seatId);
- seatGrid[row][col] = true;
- startRowIndex += rowCharCount + colCharCount + 1;
- }
- std::cout << "Highest seat ID is: " << seatIdMax << std::endl;
- for (uint64_t iRow = 1; iRow < rowSize - 1; ++iRow) {
- for (uint64_t iCol = 1; iCol < colSize - 1; ++iCol) {
- if (!seatGrid[iRow][iCol] && seatGrid[iRow][iCol - 1] && seatGrid[iRow][iCol + 1]) {
- std::cout << "Your seat ID is: " << calculateSeatId(iRow, iCol, colSize)
- << std::endl;
- return 0;
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement