/** * Copyright (c) 2020 Nicba1010 All rights reserved. */ #include #include #include #include #include /** * 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.
* 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(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(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(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; } } } }