// // Created by Grant Horner on 12/1/25. // #include #include #include #include #include #include "doctest.h" enum Direction { L = 'L', R = 'R', }; struct Instruction { Direction direction; uint32_t amount; }; Instruction parse_instruction(std::string_view line) { assert(!line.empty()); const auto direction = static_cast(line[0]); uint32_t amount; std::from_chars(&line[1], line.data() + line.size(), amount); return Instruction{direction, amount}; } template<> struct std::formatter : std::formatter { static auto format(const Instruction &i, std::format_context &ctx) { return std::format_to(ctx.out(), "Instruction[direction: {}, amount: {}]", static_cast(i.direction), i.amount); } }; const std::string sample = "L68\n" "L30\n" "R48\n" "L5\n" "R60\n" "L55\n" "L1\n" "L99\n" "R14\n" "L82\n"; uint64_t spin2(int &value, Instruction i) { uint64_t spins = i.amount / 100; int amount_to_spin = i.amount % 100; if (i.direction == L) { amount_to_spin *= -1; } value += amount_to_spin; if (value == 0) { spins++; } else if (value < 0) { spins++; value = 100 + value; } else if (100 < value) { spins++; value = value - 100; } return spins; } bool spin(int &value, Instruction i) { value += static_cast(i.amount) * (i.direction == L ? -1 : 1); value %= 100; return value == 0; } uint32_t solve_first(const std::string &input) { int value = 50; uint32_t spins = 0; for (const auto instr: std::views::split(input, '\n') | std::views::transform([](auto s) { return std::string_view(s); }) | std::views::filter([](const std::string_view s) { return !s.empty(); }) | std::views::transform(parse_instruction) ) { if (spin(value, instr)) { spins++; } // std::println("Total spins: {}, instruction: {}, value: {}", spins, instr, value); } return spins; } TEST_CASE("puzzle 1") { CHECK(solve_first(sample) == 3); std::ifstream input("day1input.txt"); CHECK(input.is_open()); std::stringstream buffer; buffer << input.rdbuf(); CHECK(solve_first(buffer.str()) == 1158); } uint32_t solve_second(const std::string &input) { int value = 50; uint32_t spins = 0; for (const auto instr: std::views::split(input, '\n') | std::views::transform([](auto s) { return std::string_view(s); }) | std::views::filter([](const std::string_view s) { return !s.empty(); }) | std::views::transform(parse_instruction) ) { spins += spin2(value, instr); // std::println("Total spins: {}, instruction: {}, value: {}", spins, instr, value); } return spins; } TEST_CASE("puzzle 2") { CHECK(solve_second(sample) == 6); std::ifstream input("day1input.txt"); CHECK(input.is_open()); std::stringstream buffer; buffer << input.rdbuf(); CHECK(solve_second(buffer.str()) == 6860); }