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 << " \n Usage:\n "
83+ << " The program requires 2 args: (part1, part2) and the path to the file."
84+ << " \n For 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 << " \n first 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