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/Makefile | 19 ++++++ 2023/15/resources/input_small.txt | 1 + 2023/15/src/part1.cpp | 33 +++++++++ 2023/15/src/part2.cpp | 136 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 189 insertions(+) create mode 100644 2023/15/Makefile create mode 100644 2023/15/resources/input_small.txt create mode 100644 2023/15/src/part1.cpp create mode 100644 2023/15/src/part2.cpp diff --git a/2023/15/Makefile b/2023/15/Makefile new file mode 100644 index 0000000..af6a294 --- /dev/null +++ b/2023/15/Makefile @@ -0,0 +1,19 @@ +CXXFLAGS := -std=c++17 +CPPFLAGS := -I../include +EXE := part1 part2 + +.PHONY: all clean configure + +all: $(EXE) + +configure: + bear -- $(MAKE) all + +%.o: %.cpp + $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@ + +clean: + rm -rf $(EXE) src/*.o compile_commands.json + +%: src/%.o + $(CXX) $^ -o $@ diff --git a/2023/15/resources/input_small.txt b/2023/15/resources/input_small.txt new file mode 100644 index 0000000..4f58f74 --- /dev/null +++ b/2023/15/resources/input_small.txt @@ -0,0 +1 @@ +rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7 diff --git a/2023/15/src/part1.cpp b/2023/15/src/part1.cpp new file mode 100644 index 0000000..6473d20 --- /dev/null +++ b/2023/15/src/part1.cpp @@ -0,0 +1,33 @@ +#include +#include + +int main(int argc, char* argv[]) +{ + int answer{}; + + if (std::ifstream input{ argv[1] }; input.is_open()) + { + std::string line; + std::getline(input,line); + + int hash{}; + for (unsigned char c : line) + { + if (c == ',') + { + answer += hash; + hash = 0; + } + else + { + hash += c; + hash *= 17; + hash %= 256; + } + } + answer += hash; + } + + std::cout << answer << std::endl; + return 0; +} 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