From d5cd72f4bc9fa29d917af652a4bbb04cf0422ddb Mon Sep 17 00:00:00 2001 From: Eric Mertens Date: Mon, 27 Mar 2023 15:59:12 -0700 Subject: [PATCH] make 13 more efficient! (no more temporaries) --- 2022/13.cpp | 65 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 23 deletions(-) diff --git a/2022/13.cpp b/2022/13.cpp index 3cc4d5f..ea6b720 100644 --- a/2022/13.cpp +++ b/2022/13.cpp @@ -9,29 +9,49 @@ #include #include +#include namespace { struct Tree { - std::variant> var; - - auto operator<(Tree const& rhs) const -> bool { - if (var.index() == 0) { - if (rhs.var.index() == 0) { - return std::get<0>(var) < std::get<0>(rhs.var); - } else { - return Tree{std::vector{*this}} < rhs; - } - } else { - if (rhs.var.index() == 0) { - return *this < Tree{std::vector{rhs}}; - } else { - return std::get<1>(var) < std::get<1>(rhs.var); - } - } - } + std::variant> rep; }; +auto operator<(Tree const& lhs, Tree const& rhs) -> bool; + +auto operator<(std::vector const& x, std::int64_t y) -> bool; +auto operator<(std::int64_t x, std::vector const& y) -> bool; + +auto operator<(Tree const& x, std::int64_t y) -> bool; +auto operator<(std::int64_t x, Tree const& y) -> bool; + +auto operator<(std::int64_t x, std::vector const& y) -> bool { + switch (y.size()) { + case 0: return false; + case 1: return x < y[0]; + default: return !(y[0] < x); + } +} + +auto operator<(std::vector const& x, std::int64_t y) -> bool { + switch (x.size()) { + case 0: return true; + default: return x[0] < y; + } +} + +auto operator<(Tree const& x, std::int64_t y) -> bool { + return std::visit([y](auto const& x_) { return x_ < y; }, x.rep); +} + +auto operator<(std::int64_t x, Tree const& y) -> bool { + return std::visit([x](auto const& y_) { return x < y_; }, y.rep); +} + +auto operator<(Tree const& lhs, Tree const& rhs) -> bool { + return std::visit(std::less(), lhs.rep, rhs.rep); +} + using Input = std::vector; auto ParseTree(std::string::iterator & begin, std::string::iterator end) -> Tree @@ -87,12 +107,12 @@ auto Part1(Input const& input) -> std::int64_t return result; } -auto Part2(Input input) -> std::int64_t +auto Part2(Input const& input) -> std::int64_t { Tree two {std::vector{Tree{std::vector{Tree{2}}}}}; Tree six {std::vector{Tree{std::vector{Tree{6}}}}}; - auto ix2 = std::count_if(input.begin(), input.end(), [&](auto x) { return x < two; }); - auto ix6 = std::count_if(input.begin(), input.end(), [&](auto x) { return x < six; }); + auto ix2 = std::count_if(input.begin(), input.end(), [&](auto const& x) { return x < two; }); + auto ix6 = std::count_if(input.begin(), input.end(), [&](auto const& x) { return x < six; }); return (ix2+1) * (ix6+2); } @@ -142,8 +162,7 @@ TEST_SUITE("2022-13 examples") { auto Main(std::istream & in, std::ostream & out) -> void { - auto input = Parse(in); - out << "count " << input.size() << std::endl; + auto const input = Parse(in); out << "Part 1: " << Part1(input) << std::endl; - out << "Part 2: " << Part2(std::move(input)) << std::endl; + out << "Part 2: " << Part2(input) << std::endl; }