From b92a50d54677abfcf63e216dc5982896a83690d2 Mon Sep 17 00:00:00 2001 From: Eric Mertens Date: Sat, 28 Jan 2023 08:39:08 -0800 Subject: [PATCH] wip 2022-16 --- 2022/16.cpp | 166 ++++++++++++++++++++++++++++++++++++++++++++ 2022/CMakeLists.txt | 3 + 2 files changed, 169 insertions(+) create mode 100644 2022/16.cpp diff --git a/2022/16.cpp b/2022/16.cpp new file mode 100644 index 0000000..44bd9bd --- /dev/null +++ b/2022/16.cpp @@ -0,0 +1,166 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +namespace { + +auto ShortestDistances(std::vector> & dist) +{ + auto const range = boost::irange(dist.size()); + for (auto const k : range) { + for (auto const i : range) { + for (auto const j : range) { + auto const new_dist = dist[i][k] + dist[k][j]; + auto & old_dist = dist[i][j]; + if (old_dist > new_dist) old_dist = new_dist; + } + } + } +} + +struct RawRoom { + std::string name; + std::uint64_t flow; + std::vector connections; +}; + +struct Room { + std::uint64_t flow; + std::vector connections; +}; + +auto Parse(std::istream & in) -> std::vector +{ + std::vector result; + std::string line; + while (std::getline(in, line)) { + RawRoom room; + using namespace boost::spirit; + auto const name = qi::as_string[+qi::alpha]; + auto const room_description = + "Valve " >> + name [ ([&](auto n) { room.name = n; }) ] >> + " has flow rate=" >> + qi::ulong_long [ ([&](auto f) { room.flow = f; }) ] >> + "; tunnel" >> -qi::string("s") >> + " lead" >> -qi::string("s") >> + " to valve" >> -qi::string("s") >> + " " >> + (name % ", ") [ ([&](auto c) { room.connections = c; }) ]; + + if (!qi::parse(line.begin(), line.end(), room_description)) { + throw std::runtime_error{"bad input line"}; + } + result.emplace_back(std::move(room)); + } + return result; +} + +auto GenerateGraph(std::vector const& raw_rooms) -> std::vector +{ + std::vector result; + std::map names; + + std::vector> distances( + raw_rooms.size(), std::vector(raw_rooms.size(), 100)); // todo max limit + + for (auto const i : boost::irange(raw_rooms.size())) { + names[raw_rooms[i].name] = i; + } + + for (auto const i : boost::irange(raw_rooms.size())) { + auto & ds = distances[i]; + for (auto const& name : raw_rooms[i].connections) { + ds[names[name]] = 1; + } + } + + ShortestDistances(distances); + + for (auto const i : boost::irange(raw_rooms.size())) { + result.push_back({raw_rooms[i].flow, std::move(distances[i])}); + } + + return result; +} + +using Valves = std::bitset<64>; + +struct State { + std::uint64_t time; + std::uint64_t flow; + std::size_t location; + Valves valves; +}; + +auto Routes(std::vector const& rooms, std::uint64_t time) -> std::map +{ + std::vector states { State{time, 0, 0, {}} }; + std::map result; + + while (!states.empty()) { + auto state = states.back(); + states.pop_back(); + + auto const& room = rooms[state.location]; + + for (auto const i : boost::irange(rooms.size())) { + auto valves = state.valves; + if (valves[i]) { continue; } + auto const flow = rooms[i].flow; + if (flow == 0) { continue; } + auto const cost = room.connections[i]; + if (cost >= state.time) { continue; } + auto const time_ = state.time - cost - 1; + + valves[i] = true; + auto const flow_ = state.flow + time_; + + if (result[valves.to_ullong()] < flow_) { + result[valves.to_ullong()] = flow_; + } + + states.push_back({ time_, state.flow + time_, i, valves}); + } + } + + return result; +} + +} // namespace + +TEST_SUITE("2022-16 examples") { + TEST_CASE("example") { + std::istringstream in { + + }; + } +} + +auto main(int argc, char** argv) -> int +{ + auto const input = Parse(*aocpp::Startup(argc, argv)); + auto const graph = GenerateGraph(input); + auto const routes = Routes(graph, 30); + + std::uint64_t p1 = 0; + for (auto const& kv : routes) { + p1 = std::max(p1, kv.second); + } + + std::cout << "Part 1: " << p1 << std::endl; + //Part2(snapshots, std::cout << "Part 2:\n"); +} diff --git a/2022/CMakeLists.txt b/2022/CMakeLists.txt index 0a790ac..d9b40c0 100644 --- a/2022/CMakeLists.txt +++ b/2022/CMakeLists.txt @@ -31,6 +31,9 @@ target_link_libraries(2022_12 aocpp) add_executable(2022_13 13.cpp) target_link_libraries(2022_13 aocpp) +add_executable(2022_16 16.cpp) +target_link_libraries(2022_16 aocpp Boost::headers) + add_executable(2022_18 18.cpp) target_link_libraries(2022_18 aocpp)