From 95afbe5174be402b681cd98ea83cc063cd23f5c0 Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Wed, 20 Dec 2023 00:54:49 +0100 Subject: aoc(2319): Aplenty --- 2023/19/src/part1.cpp | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 2023/19/src/part1.cpp (limited to '2023/19/src/part1.cpp') diff --git a/2023/19/src/part1.cpp b/2023/19/src/part1.cpp new file mode 100644 index 0000000..b63f05d --- /dev/null +++ b/2023/19/src/part1.cpp @@ -0,0 +1,125 @@ +#include +#include +#include +#include +#include +#include + +#include "util.h" + +using Name = std::string; +using Part = std::array; +using Cond = std::function; +using Rule = std::pair; +using Workflow = std::vector; +using Workflows = std::unordered_map; + +const std::unordered_map fields{ {'x', 0}, {'m', 1}, {'a', 2}, {'s', 3} }; + +std::pair,Workflows> parse(const char* file) +{ + using namespace util::separators; + + Workflows wfs; + std::vector parts; + + if (std::ifstream input{ file }; input.is_open()) + { + std::string line; + std::getline(input,line); + while (not line.empty()) + { + auto bw = line.find('{'); + Name name = line.substr(0, bw); + + std::vector rules; + line = line.substr(bw + 1, line.size() - bw - 2); + for (auto srule : util::split(std::string_view{ line })) + { + auto tokens = util::split(srule); + if (tokens.size() > 1) + { + int f = fields.at(tokens[0][0]); + int v = std::stoi(std::string(tokens[0].substr(2))); + switch (tokens[0][1]) + { + case '<': + rules.push_back({ + [f,v](const Part& p) { return p[f] < v; }, + Name{ tokens[1] } + }); + break; + default: + rules.push_back({ + [f,v](const Part& p) { return p[f] > v; }, + Name{ tokens[1] } + }); + }; + } + else + { + rules.push_back({ + [](const Part& p) { return true; }, + Name{ tokens[0] } + }); + } + } + wfs.insert({ name, std::move(rules) }); + std::getline(input,line); + } + + while (not std::getline(input,line).eof()) + { + Part part; int i{}; + util::accumulate(std::string_view{ line }.substr(1, line.size() - 2), + [&part,&i](std::string_view& v) + { + part[i++] = std::stoi(std::string{ v.substr(2) }); + } + ); + parts.push_back(std::move(part)); + } + } + return { std::move(parts), std::move(wfs) }; +} + +Name apply_workflow(const Workflow& wf, const Part& p) +{ + for (const auto& rule : wf) + { + auto [cond, name] = rule; + if (cond(p)) return name; + } + return "R"; +} + +int value(const Part& p) +{ + return p[0] + p[1] + p[2] + p[3]; +} + +int process(const Part& p, const Workflows& wfs) +{ + Name wname = "in"; + while (wname != "A") + { + if (wname == "R") return 0; + wname = apply_workflow(wfs.at(wname), p); + } + return value(p); +} + +int main(int argc, char* argv[]) +{ + int answer{}; + + auto [parts, workflows] = parse(argv[1]); + + for (const auto& part : parts) + { + answer += process(part, workflows); + } + + std::cout << answer << std::endl; + return 0; +} -- cgit v1.2.3