This commit is contained in:
Eric Mertens 2023-01-25 18:14:30 -05:00
parent eade441ba2
commit fd2457154d
3 changed files with 56 additions and 36 deletions

View File

@ -38,16 +38,24 @@ auto Parse(std::istream & in) -> Input
/// @return top 1 and sum of top 3 calorie counts
auto Solve(Input const& input) -> std::pair<std::int64_t, std::int64_t>
{
if (input.size() < 3) { throw std::runtime_error{"bad input"}; }
std::vector<std::int64_t> elves;
for (auto const& elf : input) {
elves.push_back(std::reduce(elf.begin(), elf.end()));
if (input.size() < 3) {
throw std::runtime_error{"bad input"};
}
std::partial_sort(elves.begin(), std::next(elves.begin(), 3), elves.end(), std::greater());
std::vector<std::int64_t> elves;
std::transform(
input.begin(), input.end(), std::back_inserter(elves),
[](auto const& elf){
return std::reduce(elf.begin(), elf.end());
});
return {elves.front(), std::reduce(elves.begin(), std::next(elves.begin(), 3))};
// Fill the top 3 array elements with the maximum values
auto const top3 = std::next(elves.begin(), 3);
std::partial_sort(elves.begin(), top3, elves.end(), std::greater());
auto const p1 = elves.front();
auto const p2 = std::reduce(elves.begin(), top3);
return {p1, p2};
}
} // namespace
@ -69,15 +77,15 @@ TEST_SUITE("2022-01 examples") {
"9000\n"
"\n"
"10000\n"};
auto entries = Parse(in);
auto [p1,p2] = Solve(entries);
auto const entries = Parse(in);
auto const [p1,p2] = Solve(entries);
CHECK(p1 == 24000);
CHECK(p2 == 45000);
}
}
auto main(int argc, char** argv) -> int {
auto [p1,p2] = Solve(Parse(*aocpp::Startup(argc, argv)));
auto const [p1,p2] = Solve(Parse(*aocpp::Startup(argc, argv)));
std::cout << "Part 1: " << p1 << std::endl;
std::cout << "Part 2: " << p2 << std::endl;
}

View File

@ -9,6 +9,8 @@
#include <vector>
#include <string_view>
#include <boost/range/irange.hpp>
#include <doctest.h>
#include <aocpp/Startup.hpp>
@ -30,42 +32,52 @@ auto Priority(char const c) -> std::int64_t
return c < 'a' ? c-'A'+27 : c-'a'+1;
}
auto Intersect(std::string const& a, std::string const& b) {
auto Intersect(
std::string::const_iterator start1, std::string::const_iterator end1,
std::string::const_iterator start2, std::string::const_iterator end2
) -> std::string
{
std::string common;
std::set_intersection(a.begin(), a.end(), b.begin(), b.end(),
std::set_intersection(
start1, end1,
start2, end2,
std::back_inserter(common));
return common;
}
auto Part1(std::vector<std::string> const& input) -> std::int64_t
auto Part1(std::vector<std::string> & input) -> std::int64_t
{
std::int64_t n {0};
for (auto const& line : input) {
auto m = line.size() / 2;
auto elf1 {line.substr(0, m)};
std::sort(elf1.begin(), elf1.end());
auto elf2 {line.substr(m)};
std::sort(elf2.begin(), elf2.end());
n += Priority(Intersect(elf1, elf2).at(0));
}
return n;
return std::transform_reduce(
input.begin(), input.end(),
std::int64_t{0}, std::plus(), // sum
[](auto & line) {
auto const mid = line.begin() + line.size() / 2;
std::sort(line.begin(), mid);
std::sort(mid, line.end());
auto const common = Intersect(line.begin(), mid, mid, line.end());
return Priority(common.at(0));
});
}
auto Part2(std::vector<std::string> input) -> std::int64_t
auto Part2(std::vector<std::string> & input) -> std::int64_t
{
std::int64_t n {0};
for (auto & line : input) {
std::sort(line.begin(), line.end());
}
for (std::size_t i = 0; i + 2 < input.size(); i += 3) {
n += Priority(Intersect(Intersect(input[i], input[i+1]), input[i+2]).at(0));
}
return n;
auto const range = boost::irange<std::size_t>(0, input.size(), 3);
return std::transform_reduce(
range.begin(), range.end(),
std::int64_t{0}, std::plus(), // sum
[&input](auto const i) {
auto const input01 = Intersect(
input[i ].begin(), input[i ].end(),
input[i+1].begin(), input[i+1].end());
auto const input012 = Intersect(
input01 .begin(), input01 .end(),
input[i+2].begin(), input[i+2].end());
return Priority(input012.at(0));
});
}
} // namespace
@ -81,12 +93,12 @@ TEST_SUITE("2022-03 examples") {
"CrZsJsPPZsGzwwsLwLmpwMDw\n"};
auto input = Parse(in);
CHECK(Part1(input) == 157);
CHECK(Part2(std::move(input)) == 70);
CHECK(Part2(input) == 70);
}
}
auto main(int argc, char** argv) -> int {
auto input = Parse(*aocpp::Startup(argc, argv));
std::cout << "Part 1: " << Part1(input) << std::endl;
std::cout << "Part 2: " << Part2(std::move(input)) << std::endl;
std::cout << "Part 2: " << Part2(input) << std::endl;
}

View File

@ -5,7 +5,7 @@ add_executable(2022_02 02.cpp)
target_link_libraries(2022_02 aocpp)
add_executable(2022_03 03.cpp)
target_link_libraries(2022_03 aocpp)
target_link_libraries(2022_03 aocpp Boost::headers)
add_executable(2022_04 04.cpp)
target_link_libraries(2022_04 aocpp)