Nicba1010 icon

Day5v2

Nicba1010 | PRO | 12/05/20 12:40:32 PM UTC | 0 ⭐ | 898 👁️ | Never ⏰ | []
C++ |

5.28 KB

|

None

|

0 👍

/

0 👎

/**
 * Copyright (c) 2020 Nicba1010 All rights reserved.
 */
 
#include <fstream>
#include <iostream>
#include <vector>
#include <ctgmath>
 
/**
 * @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 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<std::string> lines;
 
    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;
 
    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;
}

Comments