#include #include #include #include #include #include #include #include #include #include namespace { using Input = std::vector; /// @brief Parse the input stream as a newline-delimited list of lists of integers /// @param in input file parsed until EOF /// @return outer list of elves, inner lists of calories auto Parse(std::istream & in) -> Input { Input results {}; std::move( std::istream_iterator{in}, std::istream_iterator{}, std::back_inserter(results) ); return results; } auto Part1(Input const& entries) -> std::int64_t { std::int64_t acc = 0; for (auto const& entry : entries) { auto lhs = std::find_if(entry.begin(), entry.end(), [](char c){ return std::isdigit(c); }); auto rhs = std::find_if(entry.rbegin(), entry.rend(), [](char c){ return std::isdigit(c); }); acc += 10 * (*lhs - '0') + (*rhs - '0'); } return acc; } auto Part2(Input const& entries) -> std::int64_t { static std::pair numbers[] = { {"one", 1}, {"two", 2}, {"three", 3}, {"four", 4}, {"five", 5}, {"six", 6}, {"seven", 7}, {"eight", 8}, {"nine", 9}, {"0",0},{"1",1},{"2",2},{"3",3},{"4",4}, {"5",5},{"6",6},{"7",7},{"8",8},{"9",9} }; std::int64_t acc = 0; for (auto const& entry : entries) { std::int64_t lhs = 0; std::int64_t rhs = 0; for (auto cursor = entry.begin(); cursor < entry.end(); cursor++) { for (auto const [k,v] : numbers) { if (std::string_view{cursor, entry.end()}.starts_with(k)) { lhs = v; goto do_rhs; } } } do_rhs: for (auto cursor = entry.end(); cursor --> entry.begin();) { std::int64_t lhs = 0; for (auto const [k,v] : numbers) { if (std::string_view{cursor, entry.end()}.starts_with(k)) { rhs = v; goto next; } } } next: acc += 10 * lhs + rhs; } return acc; } } // namespace auto Main(std::istream & in, std::ostream & out) -> void { auto const entries = Parse(in); out << "Part 1: " << Part1(entries) << std::endl; out << "Part 2: " << Part2(entries) << std::endl; }