1+ #include < fstream>
2+ #include < iostream>
3+ #include < map>
4+ #include < memory>
5+ #include < string>
6+ #include < vector>
7+ #include < map>
8+
9+ int level = 0 ;
10+ enum class Type {
11+ NONE, INT, STRING, VECTOR, MAP
12+ };
13+
14+ struct Node ;
15+
16+ struct Node {
17+ Type type = Type::NONE;
18+ int val_i;
19+ std::string val_s;
20+ std::vector<std::unique_ptr<Node>> val_v;
21+ std::map<std::string, std::unique_ptr<Node>> val_m;
22+ };
23+
24+ std::pair<std::unique_ptr<Node>, int > parse (const int idx, const std::string& input);
25+ std::pair<std::map<std::string, std::unique_ptr<Node>>, int > parse_map (const int idx, const std::string& input);
26+ std::pair<std::vector<std::unique_ptr<Node>>, int > parse_vector (const int idx, const std::string& input);
27+
28+ std::pair<std::unique_ptr<Node>, int > parse (const int idx, const std::string& input) {
29+ // std::cout << "Parsing. starting at" << idx << ' ' << input[idx] << '\n';
30+ auto ptr = std::unique_ptr<Node>(new Node);
31+ int next_idx = idx;
32+ if (input[idx] == ' [' ) {
33+ ptr->type = Type::VECTOR;
34+ auto p = parse_vector (idx+1 , input);
35+ ptr->val_v = std::move (p.first );
36+ next_idx = p.second ;
37+ }
38+ else if (input[idx] == ' {' ) {
39+ ptr->type = Type::MAP;
40+ auto p = parse_map (idx+1 , input);
41+ ptr->val_m = std::move (p.first );
42+ next_idx = p.second ;
43+ }
44+ else if (isdigit (input[idx]) || input[idx] == ' -' ) {
45+ ptr->type = Type::INT;
46+ next_idx = idx+1 ;
47+ while (isdigit (input[next_idx])) {
48+ next_idx++;
49+ }
50+ ptr->val_i = std::stoi (input.substr (idx, next_idx-idx));
51+ }
52+ else if (isalpha (input[idx]) || input[idx] == ' "' ) {
53+ ptr->type = Type::STRING;
54+ next_idx = idx;
55+ while (isalpha (input[next_idx]) || input[next_idx] == ' "' ) {
56+ next_idx++;
57+ }
58+ ptr->val_s = input.substr (idx, next_idx - idx);
59+ }
60+ // if (input[next_idx] == ',') next_idx++;
61+ // std::cout << "Done parsing. next idx is: " << next_idx << ' ' << input[next_idx] << '\n';
62+ return {std::move (ptr), next_idx};
63+ }
64+
65+ std::pair<std::vector<std::unique_ptr<Node>>, int > parse_vector (const int idx, const std::string& input) {
66+ // std::cout << "Parsing vector" << '\n';
67+ level++;
68+ std::vector<std::unique_ptr<Node>> ptrs;
69+ if (input[idx] == ' ]' ) {
70+ level--;
71+ return {std::move (ptrs), idx+1 };
72+ }
73+ int i = idx;
74+ while (i < input.size ()) {
75+ auto ret = parse (i, input);
76+ ptrs.push_back (std::move (ret.first ));
77+ if (input[ret.second ] == ' ,' ) {
78+ i = ret.second + 1 ;
79+ } else if (input[ret.second ] == ' ]' ) {
80+ i = ret.second + 1 ;
81+ break ;
82+ } else {
83+ std::cout << " This should not happen" << ' \n ' ;
84+ exit (0 );
85+ }
86+ }
87+ // std::cout << "Done parsing vector. next idx is: " << i << ' ' << input[i] << '\n';
88+ level--;
89+ return {std::move (ptrs), i};
90+ }
91+
92+ std::pair<std::map<std::string, std::unique_ptr<Node>>, int > parse_map (const int idx, const std::string& input) {
93+ // std::cout << "Parsing map" << '\n';
94+ level++;
95+ std::map<std::string, std::unique_ptr<Node>> ptrs;
96+ if (input[idx] == ' }' ) {
97+ level--;
98+ return {std::move (ptrs), idx+1 };
99+ }
100+ int i = idx;
101+ while (i < input.size ()) {
102+ const int end = input.find (' :' , i);
103+ const auto key = input.substr (i, end - i);
104+ auto ret = parse (end + 1 , input);
105+ ptrs[key] = std::move (ret.first );
106+ i = ret.second ;
107+ if (input[ret.second ] == ' }' ) {
108+ i++;
109+ break ;
110+ }
111+ else if (input[ret.second ] == ' ,' ) i++;// continue the loop
112+ else {
113+ std::cout << " This should not happen" << ' \n ' ;
114+ exit (0 );
115+ }
116+ }
117+ // std::cout << "Done parsing map.next idx is: " << i << ' ' << input[i] << '\n';
118+ level--;
119+ return {std::move (ptrs), i};
120+ }
121+
122+ void print (std::unique_ptr<Node>& n, int spaces) {
123+ std::cout << ' \n ' ;
124+ for (int i = 0 ; i < spaces; i++) std::cout << " > " ;
125+ if (n->type == Type::INT) {
126+ std::cout << n->val_i << ' \n ' ;
127+ }
128+ if (n->type == Type::STRING) {
129+ std::cout << n->val_s << ' \n ' ;
130+ }
131+ if (n->type == Type::VECTOR) {
132+ for (auto & ele : n->val_v ) {
133+ print (ele, spaces + 1 );
134+ }
135+ }
136+ if (n->type == Type::MAP) {
137+ for (auto & [key, val] : n->val_m ) {
138+ std::cout << key << " : " ;
139+ print (val, spaces + 1 );
140+ }
141+ }
142+ }
143+
144+ void traverse (std::unique_ptr<Node>& n, int spaces, int & total) {
145+ if (n->type == Type::INT) {
146+ total += n->val_i ;
147+ }
148+ else if (n->type == Type::STRING) {
149+ }
150+ else if (n->type == Type::VECTOR) {
151+ for (auto & ele : n->val_v ) {
152+ traverse (ele, spaces + 1 , total);
153+ }
154+ }
155+ if (n->type == Type::MAP) {
156+ for (auto & [key, val] : n->val_m ) {
157+ traverse (val, spaces + 1 , total);
158+ }
159+ }
160+ }
161+
162+ int main (int argc, char * argv[]) {
163+ std::string input = " ../input/day_12_input" ;
164+ if (argc > 1 ) {
165+ input = argv[1 ];
166+ }
167+
168+ std::ifstream file (input);
169+ std::string line;
170+ while (std::getline (file, line)) {
171+ auto ret = parse (0 , line);
172+ if (line.size () > ret.second ) {
173+ std::cout << " Not parsed fully" << ' \n ' ;
174+ }
175+ // auto ret = std::pair<std::unique_ptr<Node>, int>();
176+ // print(ret.first, 0);
177+ int ans = 0 ;
178+ traverse (ret.first , 0 , ans);
179+ std::cout << ans << ' \n ' ;
180+ }
181+
182+ return 0 ;
183+ }
0 commit comments