Skip to content

Commit 56cf62e

Browse files
author
Pascal Guenther
committed
2024 Day 03
1 parent 5ce98ab commit 56cf62e

File tree

8 files changed

+215
-3
lines changed

8 files changed

+215
-3
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cmake_minimum_required(VERSION 3.16)
22

3-
project(AdventOfCode VERSION 2024.12.02)
3+
project(AdventOfCode VERSION 2024.12.03)
44

55
option(AOC_TESTING "Enable testing for AdventOfCode" On)
66

cpp/src/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ include(FetchContent)
44
FetchContent_Declare(
55
CompileTimeRegularExpressions
66
GIT_REPOSITORY https://github.com/hanickadot/compile-time-regular-expressions.git
7-
GIT_TAG v3.7.1
7+
GIT_TAG v3.9.0
88
)
99
FetchContent_MakeAvailable(CompileTimeRegularExpressions)
1010

1111
target_link_libraries(aoc_y2024_core PRIVATE
1212
ctre
1313
)
1414

15-
set(AOC_Y2024_DAYS_LIST "01;02")
15+
set(AOC_Y2024_DAYS_LIST "01;02;03")
1616
set(AOC_Y2024_DAYS_LIST ${AOC_Y2024_DAYS_LIST} PARENT_SCOPE)
1717
set(AOC_Y2024_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} PARENT_SCOPE)
1818

cpp/src/day03.cpp

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#include "ipuzzle.hpp"
2+
#include "puzzle_common.hpp"
3+
#include "utils.hpp"
4+
#include "ctre.hpp"
5+
6+
#include <algorithm>
7+
#include <array>
8+
#include <memory>
9+
#include <numeric>
10+
#include <ranges>
11+
#include <string_view>
12+
#include <utility>
13+
#include <vector>
14+
15+
namespace AOC::Y2024
16+
{
17+
18+
namespace {
19+
using Operand = uint32_t;
20+
enum Instruction {mul, do_, dont,};
21+
struct Operation {
22+
Instruction instruction;
23+
std::pair<Operand, Operand> operands;
24+
};
25+
using Parsed = std::vector<Operation>;
26+
27+
AOC_Y2024_CONSTEXPR auto parse_input(std::string_view input_string_view)
28+
{
29+
Parsed parsed;
30+
const auto matches = ctre::multiline_search_all<R"((?:mul\((\d+),(\d+)\))|(do\(\)|don't\(\)))">(input_string_view);
31+
for (const auto& match : matches)
32+
{
33+
if (match.get<0>() == "do()")
34+
{
35+
parsed.emplace_back(Operation{.instruction = Instruction::do_});
36+
}
37+
else if (match.get<0>() == "don't()")
38+
{
39+
parsed.emplace_back(Operation{.instruction = Instruction::dont});
40+
}
41+
else
42+
{
43+
parsed.emplace_back(Operation{.instruction = Instruction::mul, .operands{ parse_number<Operand>(match.get<1>()), parse_number<Operand>(match.get<2>())}});
44+
}
45+
}
46+
return parsed;
47+
}
48+
49+
AOC_Y2024_CONSTEXPR auto part_1(const Parsed &parsed)
50+
{
51+
return std::accumulate(
52+
parsed.begin(), parsed.end(), 0u, [](const auto &acc, const auto &operation){
53+
return (operation.instruction == Instruction::mul)
54+
? (acc + (operation.operands.first * operation.operands.second))
55+
: acc;
56+
});
57+
}
58+
59+
AOC_Y2024_CONSTEXPR auto part_2(const auto &parsed)
60+
{
61+
return std::accumulate(
62+
parsed.begin(), parsed.end(), 0u, [enabled = true] (const auto &acc, const auto &operation) mutable {
63+
switch(operation.instruction) {
64+
using enum Instruction;
65+
case do_:
66+
enabled = true;
67+
return acc;
68+
case dont:
69+
enabled = false;
70+
return acc;
71+
default:
72+
return acc + (enabled ? (operation.operands.first * operation.operands.second): 0u);
73+
}
74+
});
75+
}
76+
}
77+
78+
class PuzzleDay03Impl final {
79+
public:
80+
AOC_Y2024_CONSTEXPR PuzzleDay03Impl(Parsed &&parsed) : parsed(parsed) {}
81+
Parsed parsed;
82+
};
83+
84+
AOC_Y2024_PUZZLE_CLASS_DECLARATION(03)
85+
86+
PuzzleDay03::PuzzleDay03(const std::string_view input)
87+
: pImpl(std::make_unique<PuzzleDay03Impl>(parse_input(input)))
88+
{
89+
}
90+
91+
PuzzleDay03::~PuzzleDay03() = default;
92+
93+
[[nodiscard]] IPuzzle::Solution_t PuzzleDay03::Part1()
94+
{
95+
if (!pImpl || (pImpl->parsed.size() < 1))
96+
{
97+
return std::monostate{};
98+
}
99+
return part_1(pImpl->parsed);
100+
}
101+
102+
[[nodiscard]] IPuzzle::Solution_t PuzzleDay03::Part2()
103+
{
104+
if (!pImpl || (pImpl->parsed.size() < 1))
105+
{
106+
return std::monostate{};
107+
}
108+
return part_2(pImpl->parsed);
109+
}
110+
111+
#if AOC_Y2024_CONSTEXPR_UNIT_TEST
112+
namespace
113+
{
114+
115+
consteval bool TestDay03()
116+
{
117+
Parsed parsed1{parse_input("xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))")};
118+
Parsed parsed2{parse_input("mul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))")};
119+
120+
if (161 != part_1(parsed1))
121+
{
122+
return false;
123+
}
124+
125+
return 48 == part_2(parsed2);
126+
}
127+
128+
static_assert(TestDay03(), "");
129+
} // namespace
130+
#endif // AOC_Y2024_CONSTEXPR_UNIT_TEST
131+
132+
} // namespace AOC::Y2024

cpp/src/puzzle_factory.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#define AOC_Y2024_SUPPORTED_PUZZLES_LIST(xMacro) \
66
xMacro(01) \
77
xMacro(02) \
8+
xMacro(03) \
89

910
namespace AOC::Y2024
1011
{

cpp/tests/test_day03.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
#include "ipuzzle.hpp"
3+
#include "puzzle_common.hpp"
4+
5+
#include <gtest/gtest.h>
6+
7+
#include <memory>
8+
#include <string_view>
9+
10+
namespace AOC::Y2024
11+
{
12+
13+
AOC_Y2024_PUZZLE_CLASS_DECLARATION(03)
14+
15+
namespace
16+
{
17+
18+
TEST(Day03Test, Part1)
19+
{
20+
auto pPuzzle = std::make_unique<PuzzleDay03>("xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))");
21+
ASSERT_EQ(std::get<std::int64_t>(pPuzzle->Part1()), 161);
22+
}
23+
24+
TEST(Day03Test, Part2)
25+
{
26+
auto pPuzzle = std::make_unique<PuzzleDay03>("mul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))");
27+
ASSERT_EQ(std::get<std::int64_t>(pPuzzle->Part2()), 48);
28+
}
29+
30+
} // namespace
31+
} // namespace AOC::Y2024

0 commit comments

Comments
 (0)