/** * Copyright (c) 2020 Nicba1010 All rights reserved. */ #include #include #include #include /** * @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 string 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 string or * lowerBoundDesignator/upperBoundDesignator. * * @return The found value. */ static uint64_t splitFind(uint64_t lowerBound, uint64_t upperBound, const std::string& 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 string, or " "lowerBoundDesignator/upperBoundDesignator!"); } } return lowerBound == upperBound ? lowerBound : throw std::runtime_error("Lower and upper bound do not " "match, possibly wrong instruction " "string!"); } /** * @brief More optimized version of splitFind. * * @param instructions Instruction string. * @param upperBoundDesignator Upper bound selector character. * * @return Calculated value. */ static uint64_t splitFindBetter(const std::string& instructions, const char upperBoundDesignator) { uint64_t result = 0; for (uint64_t iChar = 0; iChar < instructions.size(); ++iChar) { result = ((result << 1) | (instructions.c_str()[iChar] == upperBoundDesignator)); } return result; } /** * @brief Calculates the seat ID according to the following equation. * @code row * 8 + col @endcode * * @param row Seat row. * @param col Seat column. * * @return The calculated seat ID */ static uint64_t calculateSeatId(uint64_t row, uint64_t col, uint64_t rowSeatIdMultiplier) { return row * rowSeatIdMultiplier + col; } int main() { std::ifstream file("../day5_bigboi3.txt"); std::vector lines; 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; const uint64_t rowSize = std::pow(2, rowCharCount); const uint64_t colSize = std::pow(2, line0.size() - rowCharCount); auto seatGrid = new bool*[rowSize]; for (int iRow = 0; iRow < rowSize; ++iRow) { seatGrid[iRow] = new bool[colSize]; } uint64_t seatIdMax = 0; std::string line; while (getline(file, line)) { uint64_t row = splitFindBetter(line.substr(0, rowCharCount), 'B'); uint64_t col = splitFindBetter(line.substr(rowCharCount), 'R'); uint64_t seatId = calculateSeatId(row, col, colSize); seatIdMax = std::max(seatIdMax, seatId); seatGrid[row][col] = true; //#ifndef NDEBUG // std::cout << "Row: " << row << " Column: " << col << " Seat ID: " << seatId << "\n"; //#endif } 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 - 1][iCol] && seatGrid[iRow + 1][iCol] && seatGrid[iRow][iCol - 1] && seatGrid[iRow][iCol + 1]) { std::cout << "Your seat ID is: " << calculateSeatId(iRow, iCol, colSize) << std::endl; } } } return 0; }