diff --git a/2016/puzzle-04-01.cc b/2016/puzzle-04-01.cc new file mode 100644 index 0000000..02b6a77 --- /dev/null +++ b/2016/puzzle-04-01.cc @@ -0,0 +1,90 @@ +// +// Created by Matthew Gretton-Dann on 03/12/2021. +// + +#include +#include +#include +#include + +using LetterCountPair = std::pair; + +/** + * \brief Ordering for LetterCount pairs + * + * This takes LetterCount pairs and orders them as defined in the puzzle. So higher counts come + * first, followed by letters in alphabetical order. + */ +struct LetterCountOrder +{ + constexpr auto operator()(LetterCountPair const& lhs, LetterCountPair const& rhs) const noexcept + -> bool + { + if (lhs.second > rhs.second) { + return true; + } + if (lhs.second == rhs.second) { + return lhs.first < rhs.first; + } + return false; + } +}; + +auto main() -> int +{ + std::string line; + std::uint64_t sum{0}; + + while (std::getline(std::cin, line)) { + std::map letter_counts; + auto it{line.begin()}; + /* Iterate over the first part which we use to get the character counts. */ + while (std::isdigit(*it) == 0 && it != line.end()) { + if (*it == '-') { + it++; + continue; + } + /* Insert or update the letter count for *it. */ + auto [lcit, success] = letter_counts.insert({*it, 1}); + if (!success) { + lcit->second++; + } + ++it; + } + + /* Read the sector number. */ + assert(it != line.end()); + std::size_t idx{0}; + std::uint64_t sector_num{std::stoul(line.substr(it - line.begin()), &idx)}; + it += static_cast(idx); + assert(*it == '['); + ++it; + + /* ordered_letters is the set of letter_counts ordered so that starting with begin() we get the + * expected letters. + */ + std::set ordered_letters; + for (auto lcit : letter_counts) { + ordered_letters.insert(lcit); + } + + /* Check that the checksum is what we want. */ + bool success = true; + auto olit = ordered_letters.begin(); + while (success && *it != ']' && it != line.end()) { + if (olit->first != *it) { + success = false; + } + ++it; + ++olit; + } + + /* If success add to the sector sum. */ + if (success) { + sum += sector_num; + } + } + + std::cout << "Sum of sector numbers: " << sum << '\n'; + return 0; +} \ No newline at end of file diff --git a/2016/puzzle-04-02.cc b/2016/puzzle-04-02.cc new file mode 100644 index 0000000..b44a165 --- /dev/null +++ b/2016/puzzle-04-02.cc @@ -0,0 +1,106 @@ +// +// Created by Matthew Gretton-Dann on 03/12/2021. +// + +#include +#include +#include +#include + +using LetterCountPair = std::pair; + +/** + * \brief Ordering for LetterCount pairs + * + * This takes LetterCount pairs and orders them as defined in the puzzle. So higher counts come + * first, followed by letters in alphabetical order. + */ +struct LetterCountOrder +{ + constexpr auto operator()(LetterCountPair const& lhs, LetterCountPair const& rhs) const noexcept + -> bool + { + if (lhs.second > rhs.second) { + return true; + } + if (lhs.second == rhs.second) { + return lhs.first < rhs.first; + } + return false; + } +}; + +auto main() -> int +{ + std::string line; + std::uint64_t sum{0}; + + while (std::getline(std::cin, line)) { + std::map letter_counts; + auto it{line.begin()}; + /* Iterate over the first part which we use to get the character counts. */ + while (std::isdigit(*it) == 0 && it != line.end()) { + if (*it == '-') { + it++; + continue; + } + /* Insert or update the letter count for *it. */ + auto [lcit, success] = letter_counts.insert({*it, 1}); + if (!success) { + lcit->second++; + } + ++it; + } + + auto name_end_it{it - 1}; + + /* Read the sector number. */ + assert(it != line.end()); + std::size_t idx{0}; + std::uint64_t sector_num{std::stoul(line.substr(it - line.begin()), &idx)}; + it += static_cast(idx); + assert(*it == '['); + ++it; + + for (auto it2{line.begin()}; it2 != name_end_it; ++it2) { + if (*it2 == '-') { + *it2 = ' '; + } + else { + *it2 = static_cast(((*it2 - 'a') + sector_num) % 26 + 'a'); + } + } + + /* ordered_letters is the set of letter_counts ordered so that starting with begin() we get the + * expected letters. + */ + std::set ordered_letters; + for (auto lcit : letter_counts) { + ordered_letters.insert(lcit); + } + + /* Check that the checksum is what we want. */ + bool success = true; + auto olit = ordered_letters.begin(); + while (success && *it != ']' && it != line.end()) { + if (olit->first != *it) { + success = false; + } + ++it; + ++olit; + } + + if (success) { + success = line.substr(0, name_end_it - line.begin()) == "northpole object storage"; + } + + /* If success add to the sector sum. */ + if (success) { + std::cout << "Name: " << line.substr(0, name_end_it - line.begin()) << '\n'; + sum += sector_num; + } + } + + std::cout << "Sum of sector numbers: " << sum << '\n'; + return 0; +} \ No newline at end of file