From eafa46252f2d41a86bf218b8af0460eeb5818eb9 Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Fri, 15 Dec 2023 18:20:56 +0100 Subject: aoc(2315): Lens Library --- 2023/15/src/part2.cpp | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 2023/15/src/part2.cpp (limited to '2023/15/src/part2.cpp') diff --git a/2023/15/src/part2.cpp b/2023/15/src/part2.cpp new file mode 100644 index 0000000..4758e86 --- /dev/null +++ b/2023/15/src/part2.cpp @@ -0,0 +1,136 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "util.h" + +using Lens = std::pair; +using Box = std::vector; +using Boxes = std::array; + +struct Cmd +{ +protected: + + int boxi_; + std::string label_; + +public: + + Cmd(const std::string& label) : boxi_{ hash(label) }, label_{label} + { + } + + virtual void apply(Boxes& boxes) const + { + auto& box = boxes[boxi_]; + auto has_same_label = [this](const auto& lens) { return lens.first == label_; }; + + if (auto lens = std::find_if(box.cbegin(), box.cend(), has_same_label); + lens != box.cend()) + { + box.erase(lens); + } + } + + static int hash(const std::string& label) + { + int hash{}; + for (unsigned char c : label) + { + hash += c; + hash *= 17; + hash %= 256; + } + return hash; + } +}; + +class Add : public Cmd +{ + int focal_; + +public: + + Add(const std::string& label, int focal) : Cmd(label), focal_{ focal } + { + } + + void apply(Boxes& boxes) const override + { + auto& box = boxes[boxi_]; + auto has_same_label = [this](const auto& lens) { return lens.first == label_; }; + + if (auto lens = std::find_if(box.begin(), box.end(), has_same_label); + lens != box.end()) + { + lens->second = focal_; + } + else + { + box.push_back({ label_, focal_ }); + } + } +}; + +int power(const Boxes& boxes) +{ + int power{}; + for (int b = 0; b < boxes.size(); ++b) + { + for(int l = 0; l < boxes[b].size(); ++l) + { + power += (b + 1) * (l + 1) * boxes[b][l].second; + } + } + return power; +} + +std::vector> parse(const char* file) +{ + using namespace util::separators; + + std::vector> cmds; + + if (std::ifstream input{ file }; input.is_open()) + { + std::string line; + std::getline(input,line); + std::string_view view{ line }; + + auto to_cmd = [&cmds](std::string_view& str) + { + auto c{ str.find_first_of("=-") }; + std::string label{ str.substr(0, c) }; + if (str[c] == '-') + { + cmds.push_back(std::make_unique(label)); + } + else + { + int focal = std::stoi( std::string{ str.substr(c + 1) } ); + cmds.push_back(std::make_unique(label, focal)); + } + }; + + util::accumulate(view, to_cmd); + } + + return cmds; +} + +int main(int argc, char* argv[]) +{ + Boxes boxes; + for (const auto& cmd : parse(argv[1])) + { + cmd->apply(boxes); + } + + std::cout << power(boxes) << std::endl; + return 0; +} -- cgit v1.2.3