From 940fe28e5f87ef281e133cbe9c551847be20bcbe Mon Sep 17 00:00:00 2001 From: zv0n Date: Wed, 15 Dec 2021 20:27:23 +0100 Subject: [PATCH] 14 --- 14/CMakeLists.txt | 22 ++++++++++ 14/input | 102 ++++++++++++++++++++++++++++++++++++++++++++++ 14/main.cpp | 102 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 226 insertions(+) create mode 100644 14/CMakeLists.txt create mode 100644 14/input create mode 100644 14/main.cpp diff --git a/14/CMakeLists.txt b/14/CMakeLists.txt new file mode 100644 index 0000000..ffcbfe4 --- /dev/null +++ b/14/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.10) +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED True) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +enable_language(CXX) + +project(AoC14) + +if(APPLE) + include_directories(/usr/local/include) + link_directories(/usr/local/lib) +endif() + +if(WIN32) + add_executable(${CMAKE_PROJECT_NAME} WIN32) +else() + add_executable(${CMAKE_PROJECT_NAME}) +endif() + +target_sources(${CMAKE_PROJECT_NAME} + PRIVATE main.cpp + ) diff --git a/14/input b/14/input new file mode 100644 index 0000000..91ad454 --- /dev/null +++ b/14/input @@ -0,0 +1,102 @@ +SHPPPVOFPBFCHHBKBNCV + +HK -> C +SP -> H +VH -> K +KS -> B +BC -> S +PS -> K +PN -> S +NC -> F +CV -> B +SH -> K +SK -> H +KK -> O +HO -> V +HP -> C +HB -> S +NB -> N +HC -> K +SB -> O +SN -> C +BP -> H +FC -> V +CF -> C +FB -> F +VP -> S +PO -> N +HN -> N +BS -> O +NF -> H +BH -> O +NK -> B +KC -> B +OS -> S +BB -> S +SV -> K +CH -> B +OB -> K +FV -> B +CP -> V +FP -> C +VC -> K +FS -> S +SS -> F +VK -> C +SF -> B +VS -> B +CC -> P +SC -> S +HS -> K +CN -> C +BN -> N +BK -> B +FN -> H +OK -> S +FO -> S +VB -> C +FH -> S +KN -> K +CK -> B +KV -> P +NP -> P +CB -> N +KB -> C +FK -> K +BO -> O +OV -> B +OC -> B +NO -> F +VF -> V +VO -> B +FF -> K +PP -> O +VV -> K +PC -> N +OF -> S +PV -> P +PB -> C +KO -> V +BF -> N +OO -> K +NV -> P +PK -> V +BV -> C +HH -> K +PH -> S +OH -> B +HF -> S +NH -> H +NN -> K +KF -> H +ON -> N +PF -> H +CS -> H +CO -> O +SO -> K +HV -> N +NS -> N +KP -> S +OP -> N +KH -> P +VN -> H diff --git a/14/main.cpp b/14/main.cpp new file mode 100644 index 0000000..ffd1dff --- /dev/null +++ b/14/main.cpp @@ -0,0 +1,102 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +using Rules = + std::unordered_map>; +using Growth = + std::unordered_map>; + +std::pair getRules(const std::string &file_name) { + Rules rules{}; + std::string input{}; + + std::ifstream file(file_name); + std::string str; + bool isFold = false; + std::getline(file, input); + std::getline(file, str); + while (std::getline(file, str)) { + auto in = str.substr(0, 2); + auto mid = str.substr(6, 1); + rules[in] = { in[0] + mid, mid + in[1] }; + } + return { input, rules }; +} + +uint64_t calculateDifferenceAfterRounds(const Rules &rules, + const std::string &text, int rounds) { + std::unordered_map pair_count{}; + for (auto &rule : rules) { + pair_count[rule.first] = 0; + } + for (int i = 0; i < text.size() - 1; i++) { + pair_count[text.substr(i, 2)] += 1; + } + for (int i = 0; i < rounds; i++) { + std::unordered_map new_pair_count{}; + for (auto &rule : rules) { + new_pair_count[rule.first] = 0; + } + for (auto &pair : pair_count) { + auto new_pairs = rules.at(pair.first); + new_pair_count[new_pairs.first] += pair.second; + new_pair_count[new_pairs.second] += pair.second; + } + pair_count = new_pair_count; + } + + std::unordered_map char_count{}; + for (auto &pair : pair_count) { + char c = pair.first[0]; + if (char_count.find(c) == char_count.end()) { + char_count[c] = pair.second; + } else { + char_count[c] += pair.second; + } + } + char_count[text.back()] += 1; + + uint64_t min = -1, max = 0; + for (auto &c : char_count) { + if (c.second < min) { + min = c.second; + } + if (c.second > max) { + max = c.second; + } + } + return max - min; +} + +uint64_t part1(Rules &rules, const std::string &text) { + return calculateDifferenceAfterRounds(rules, text, 10); +} + +uint64_t part2(Rules &rules, const std::string &text) { + return calculateDifferenceAfterRounds(rules, text, 40); +} + +int main(int argc, char **argv) { + if (argc < 2) { + std::cerr << "You must provide input file!" << std::endl; + return 1; + } + auto text_and_rules = getRules(argv[1]); + auto &text = text_and_rules.first; + auto &rules = text_and_rules.second; + + std::cout << "The difference between the most common and least common " + "letters after 10 rounds is \033[91;1m" + << part1(rules, text) << "\033[0m." << std::endl; + + std::cout << "The difference between the most common and least common " + "letters after 40 rounds is \033[91;1m" + << part2(rules, text) << "\033[0m." << std::endl; + return 0; +}