Skip to content

Commit dba243f

Browse files
author
bt
committed
day 19
1 parent 9bed464 commit dba243f

File tree

3 files changed

+228
-0
lines changed

3 files changed

+228
-0
lines changed

CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ add_compile_options(-Wall -Wextra -Wpedantic -O2)
77
function(add_challenge name)
88
add_executable(${name} ${CMAKE_CURRENT_SOURCE_DIR}/src/${name}.cpp)
99
target_include_directories(${name} PRIVATE ${CMAKE_SOURCE_DIR}/include)
10+
set_property(TARGET ${name} PROPERTY CXX_STANDARD 20)
1011
endfunction(add_challenge)
1112

1213
add_challenge(day1)
@@ -23,6 +24,11 @@ add_challenge(day11)
2324
add_challenge(day12)
2425
add_challenge(day13)
2526
add_challenge(day14)
27+
add_challenge(day15)
28+
add_challenge(day16)
29+
add_challenge(day17)
30+
add_challenge(day18)
31+
add_challenge(day19)
2632

2733
add_custom_command(TARGET day1
2834
COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_CURRENT_SOURCE_DIR}/data" "./data"

include/Cursor.hpp

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#pragma once
2+
3+
// #include <space
4+
5+
class Cursor final
6+
{
7+
public:
8+
enum class Direction{Up = 0, Right = 1, Down = 2, Left=3, Sentinel=4};
9+
10+
Cursor() = default;
11+
12+
explicit constexpr Cursor(Direction initDirection, int initX, int initY)
13+
: m_direction{initDirection}
14+
, m_x{initX}
15+
, m_y{initY}
16+
{}
17+
18+
[[nodiscard]] constexpr int x() const noexcept {
19+
return m_x;
20+
}
21+
22+
[[nodiscard]] constexpr int y() const noexcept {
23+
return m_y;
24+
}
25+
26+
[[nodiscard]] constexpr Direction direction() const noexcept {
27+
return m_direction;
28+
}
29+
30+
constexpr void stepUp() noexcept {
31+
--m_x;
32+
}
33+
34+
constexpr void stepDown() noexcept {
35+
++m_x;
36+
}
37+
38+
constexpr void stepLeft() noexcept {
39+
--m_y;
40+
}
41+
42+
constexpr void stepRight() noexcept {
43+
++m_y;
44+
}
45+
46+
47+
constexpr void move() noexcept {
48+
switch (m_direction)
49+
{
50+
case Direction::Up:
51+
stepUp();
52+
break;
53+
case Direction::Down:
54+
stepDown();
55+
break;
56+
case Direction::Left:
57+
stepLeft();
58+
break;
59+
case Direction::Right:
60+
stepRight();
61+
break;
62+
}
63+
}
64+
65+
constexpr void stepBack() noexcept {
66+
switch (m_direction)
67+
{
68+
case Direction::Up:
69+
stepDown();
70+
break;
71+
case Direction::Left:
72+
stepRight();
73+
break;
74+
case Direction::Down:
75+
stepUp();
76+
break;
77+
case Direction::Right:
78+
stepLeft();
79+
break;
80+
}
81+
}
82+
83+
constexpr void turnRight() noexcept {
84+
constexpr auto sentinelInt = static_cast<int>(Direction::Sentinel);
85+
m_direction = static_cast<Direction>((static_cast<int>(m_direction) + 1) % sentinelInt);
86+
}
87+
88+
constexpr void setDirection(Direction dir) noexcept {
89+
m_direction = dir;
90+
}
91+
92+
[[nodiscard]] constexpr bool operator==(const Cursor&) const = default;
93+
94+
[[nodiscard]] constexpr bool operator!=(const Cursor&) const = default;
95+
96+
private:
97+
Direction m_direction{Direction::Up};
98+
int m_x{}, m_y{};
99+
};

src/day19.cpp

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#include "common_headers.hpp"
2+
3+
#include <sstream>
4+
#include <unordered_set>
5+
6+
[[nodiscard]] size_t solveFirstPart(const std::unordered_set<std::string> &patterns, const std::vector<std::string>& designs)
7+
{
8+
size_t count{};
9+
std::string search;
10+
std::vector<int> match;
11+
for(const auto& design : designs) {
12+
match.clear();
13+
match.resize(design.size() + 1, 0);
14+
match[0] = 1;
15+
16+
for(size_t i = 0; i < design.size(); ++i) {
17+
search.clear();
18+
for(int j = i; j >= 0 && match[i + 1] == 0; --j) {
19+
const auto substr = design.substr(j, i - j + 1);
20+
match[i + 1] = match[j] && (patterns.count(substr) > 0);
21+
}
22+
}
23+
count += (match.back() == 1);
24+
}
25+
std::cerr << "\n";
26+
return count;
27+
}
28+
29+
[[nodiscard]] size_t solveSecondPart(const std::unordered_set<std::string> &patterns, const std::vector<std::string>& designs)
30+
{
31+
size_t count{};
32+
std::string search;
33+
std::vector<size_t> match;
34+
for(const auto& design : designs) {
35+
match.clear();
36+
match.resize(design.size() + 1, 0);
37+
match[0] = 1;
38+
39+
for(size_t i = 0; i < design.size(); ++i) {
40+
search.clear();
41+
for(int j = i; j >= 0; --j) {
42+
const auto substr = design.substr(j, i - j + 1);
43+
if(match[j] != 0 && (patterns.count(substr) > 0)) {
44+
match[i + 1] += match[j];
45+
}
46+
}
47+
}
48+
49+
count += match.back();
50+
}
51+
std::cerr << "\n";
52+
return count;
53+
}
54+
55+
56+
57+
58+
[[nodiscard]] std::unordered_set<std::string> parsePatterns(const std::string& pattern)
59+
{
60+
std::unordered_set<std::string> patterns;
61+
62+
std::stringstream ss{pattern};
63+
std::string line;
64+
while((ss >> line)) {
65+
if(line.back() == ',') {
66+
line.pop_back();
67+
}
68+
patterns.emplace(line);
69+
}
70+
return patterns;
71+
}
72+
73+
[[nodiscard]] std::pair<std::unordered_set<std::string>, std::vector<std::string>> parseInput(const std::vector<std::string>& inputVec)
74+
{
75+
auto patterns = parsePatterns(inputVec.at(0));
76+
std::vector<std::string> designs(std::next(inputVec.begin(), 2), inputVec.end());
77+
return {std::move(patterns), std::move(designs)};
78+
}
79+
80+
void printHelp()
81+
{
82+
std::cerr << "\nUsage:\n"
83+
<< "The program requires 2 args: (part1, part2) and the path to the file."
84+
<< "\nFor example, ./day7 part1 data/day7.txt";
85+
}
86+
87+
int main(int argc, char* argv[])
88+
{
89+
if(argc != 3) {
90+
printHelp();
91+
return 1;
92+
}
93+
94+
std::string_view task{argv[1]};
95+
if(task != "part1" && task != "part2") {
96+
std::cerr << "\nfirst arg can be either `part1` or `part2`\n";
97+
printHelp();
98+
return 1;
99+
}
100+
101+
std::vector<std::string> inputVec;
102+
readInput(argv[2], std::back_inserter(inputVec));
103+
104+
105+
auto [patterns, designs] = parseInput(inputVec);
106+
107+
// for(auto p : patterns) {
108+
// std::cerr << "\np `" << p <<"`";
109+
// }
110+
111+
// for(auto s : designs) {
112+
// std::cerr << "\n" << s;
113+
// }
114+
115+
if(task == "part1") {
116+
std::cout << solveFirstPart(patterns, designs);
117+
}
118+
else {
119+
std::cout << solveSecondPart(patterns, designs);
120+
}
121+
122+
return 0;
123+
}

0 commit comments

Comments
 (0)