Skip to content

Commit 374dba6

Browse files
committed
Add 2015 day 12 cpp
1 parent 2a8d30e commit 374dba6

File tree

5 files changed

+376
-2
lines changed

5 files changed

+376
-2
lines changed

2015/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ This folder contains solutions to each of the problems in Advent of Code 2015 in
1515
| <nobr> [Day 9: All in a Single Night](https://adventofcode.com/2015/day/9) </nobr> | <nobr> [Part 1](/2015/cpp/day_09a.cpp) [Part 2](/2015/cpp/day_09b.cpp) </nobr> | [Link](/2015/input/day_09_input)|[Link](/2015/sample_input/day_09_sample_input)|[Link](/2015/puzzles/day_09_puzzle)|
1616
| <nobr> [Day 10: Elves Look, Elves Say](https://adventofcode.com/2015/day/10) </nobr> | <nobr> [Part 1](/2015/cpp/day_10a.cpp) [Part 2](/2015/cpp/day_10b.cpp) </nobr> |[Link](/2015/input/day_10_input)|[Link](/2015/sample_input/day_10_sample_input)|[Link](/2015/puzzles/day_10_puzzle)|
1717
| <nobr> [Day 11: Corporate Policy](https://adventofcode.com/2015/day/11) </nobr> | <nobr> [Part 1](/2015/cpp/day_11a.cpp) [Part 2](/2015/cpp/day_11b.cpp) </nobr> |[Link](/2015/input/day_11_input)|[Link](/2015/sample_input/day_11_sample_input)|[Link](/2015/puzzles/day_11_puzzle)|
18-
| <nobr> [Day 12: ](https://adventofcode.com/2015/day/12) </nobr> | <nobr> [Part 1](/2015/cpp/day_12a.cpp) [Part 2](/2015/cpp/day_12b.cpp) </nobr> |[Link](/2015/input/day_12_input)|[Link](/2015/sample_input/day_12_sample_input)|[Link](/2015/puzzles/day_12_puzzle)|
18+
| <nobr> [Day 12: JSAbacusFramework.io](https://adventofcode.com/2015/day/12) </nobr> | <nobr> [Part 1](/2015/cpp/day_12a.cpp) [Part 2](/2015/cpp/day_12b.cpp) </nobr> |[Link](/2015/input/day_12_input)|[Link](/2015/sample_input/day_12_sample_input)|[Link](/2015/puzzles/day_12_puzzle)|
1919
| <nobr> [Day 13: ](https://adventofcode.com/2015/day/13) </nobr> | <nobr> [Part 1](/2015/cpp/day_13a.cpp) [Part 2](/2015/cpp/day_13b.cpp) </nobr> |[Link](/2015/input/day_13_input)|[Link](/2015/sample_input/day_13_sample_input)|[Link](/2015/puzzles/day_13_puzzle)|
2020
| <nobr> [Day 14: ](https://adventofcode.com/2015/day/14) </nobr> | <nobr> [Part 1](/2015/cpp/day_14a.cpp) [Part 2](/2015/cpp/day_14b.cpp) </nobr> |[Link](/2015/input/day_14_input)|[Link](/2015/sample_input/day_14_sample_input)|[Link](/2015/puzzles/day_14_puzzle)|
2121
| <nobr> [Day 15: ](https://adventofcode.com/2015/day/15) </nobr> | <nobr> [Part 1](/2015/cpp/day_15a.cpp) [Part 2](/2015/cpp/day_15b.cpp) </nobr> |[Link](/2015/input/day_15_input)|[Link](/2015/sample_input/day_15_sample_input)|[Link](/2015/puzzles/day_15_puzzle)|

2015/cpp/day_12a.cpp

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
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+
}

2015/cpp/day_12b.cpp

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
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+
auto ptr = std::unique_ptr<Node>(new Node);
30+
int next_idx = idx;
31+
if (input[idx] == '[') {
32+
ptr->type = Type::VECTOR;
33+
auto p = parse_vector(idx+1, input);
34+
ptr->val_v = std::move(p.first);
35+
next_idx = p.second;
36+
}
37+
else if (input[idx] == '{') {
38+
ptr->type = Type::MAP;
39+
auto p = parse_map(idx+1, input);
40+
ptr->val_m = std::move(p.first);
41+
next_idx = p.second;
42+
}
43+
else if (isdigit(input[idx]) || input[idx] == '-') {
44+
ptr->type = Type::INT;
45+
next_idx = idx+1;
46+
while(isdigit(input[next_idx])) {
47+
next_idx++;
48+
}
49+
ptr->val_i = std::stoi(input.substr(idx, next_idx-idx));
50+
}
51+
else if (isalpha(input[idx]) || input[idx] == '"') {
52+
ptr->type = Type::STRING;
53+
next_idx = idx;
54+
while(isalpha(input[next_idx]) || input[next_idx] == '"') {
55+
next_idx++;
56+
}
57+
ptr->val_s = input.substr(idx, next_idx - idx);
58+
}
59+
return {std::move(ptr), next_idx};
60+
}
61+
62+
std::pair<std::vector<std::unique_ptr<Node>>, int> parse_vector(const int idx, const std::string& input) {
63+
std::vector<std::unique_ptr<Node>> ptrs;
64+
if (input[idx] == ']') {
65+
return {std::move(ptrs), idx+1};
66+
}
67+
int i = idx;
68+
while (i < input.size()) {
69+
auto ret = parse(i, input);
70+
ptrs.push_back(std::move(ret.first));
71+
if (input[ret.second] == ',') {
72+
i = ret.second + 1;
73+
} else if (input[ret.second] == ']') {
74+
i = ret.second + 1;
75+
break;
76+
} else {
77+
std::cout << "This should not happen" << '\n';
78+
exit(0);
79+
}
80+
}
81+
return {std::move(ptrs), i};
82+
}
83+
84+
std::pair<std::map<std::string, std::unique_ptr<Node>>, int> parse_map(const int idx, const std::string& input) {
85+
std::map<std::string, std::unique_ptr<Node>> ptrs;
86+
if (input[idx] == '}') {
87+
return {std::move(ptrs), idx+1};
88+
}
89+
int i = idx;
90+
while (i < input.size()) {
91+
const int end = input.find(':', i);
92+
const auto key = input.substr(i, end - i);
93+
auto ret = parse(end + 1, input);
94+
ptrs[key] = std::move(ret.first);
95+
i = ret.second;
96+
if (input[ret.second] == '}') {
97+
i++;
98+
break;
99+
}
100+
else if (input[ret.second] == ',') i++;// continue the loop
101+
else {
102+
std::cout << "This should not happen" << '\n';
103+
exit(0);
104+
}
105+
}
106+
return {std::move(ptrs), i};
107+
}
108+
109+
void print(std::unique_ptr<Node>& n, int spaces) {
110+
// std::cout << '\n';
111+
for (int i = 0; i < spaces; i++) std::cout << "> ";
112+
if (n->type == Type::INT) {
113+
std::cout << n->val_i << '\n';
114+
}
115+
if (n->type == Type::STRING) {
116+
std::cout << n->val_s << '\n';
117+
}
118+
if (n->type == Type::VECTOR) {
119+
for (auto & ele : n->val_v) {
120+
print(ele, spaces + 1);
121+
}
122+
}
123+
if (n->type == Type::MAP) {
124+
for (auto & [key, val] : n->val_m) {
125+
std::cout << key << ": " << '\n';
126+
print(val, spaces + 1);
127+
}
128+
}
129+
}
130+
131+
std::pair<bool, int> traverse(std::unique_ptr<Node>& n, int spaces) {
132+
int total = 0;
133+
bool to_add = true;
134+
if (n->type == Type::INT) {
135+
total += n->val_i;
136+
}
137+
else if (n->type == Type::STRING) {
138+
if (n->val_s == "\"red\"") {
139+
// std::cout << "Red detected" << '\n';
140+
return {false, 0};
141+
}
142+
}
143+
else if (n->type == Type::VECTOR) {
144+
for (auto & ele : n->val_v) {
145+
const auto [to_add, intermediate_total] = traverse(ele, spaces + 1);
146+
total += intermediate_total;
147+
}
148+
}
149+
else if (n->type == Type::MAP) {
150+
for (auto & [key, val] : n->val_m) {
151+
if (key == "red") return {false, 0};
152+
const auto [to_add, intermediate_total] = traverse(val, spaces + 1);
153+
if (!to_add) return {true, 0};
154+
total += intermediate_total;
155+
}
156+
}
157+
return {true, total};
158+
}
159+
160+
int main(int argc, char* argv[]) {
161+
std::string input = "../input/day_12_input";
162+
if (argc > 1) {
163+
input = argv[1];
164+
}
165+
166+
std::ifstream file(input);
167+
std::string line;
168+
while(std::getline(file, line)) {
169+
auto ret = parse(0, line);
170+
if (line.size() > ret.second) {
171+
std::cout << "Not parsed fully" << '\n';
172+
}
173+
// print(ret.first, 0);
174+
const auto [allowed, total] = traverse(ret.first, 0);
175+
std::cout << (allowed ? total : 0) << '\n';
176+
}
177+
178+
return 0;
179+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[1,2,3]
2+
{"a":2,"b":4}
3+
[[[3]]]
4+
{"a":{"b":4},"c":-1}
5+
{"a":[-1,1]}
6+
[-1,{"a":1}]
7+
[]
8+
{}
9+
[1,2,3]
10+
[1,{"c":"red","b":2},3]
11+
{"d":"red","e":[1,2,3,4],"f":5}
12+
[1,"red",5]

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ This repository contains solutions to the Advent of Code puzzles.
1414
|2018 |1-25 | - | [Link](/2018/) |[Link](/2018/README.md) |
1515
|2017 |1-25 | - | [Link](/2017/) |[Link](/2017/README.md) |
1616
|2016 |1-25 | - | [Link](/2016/) |[Link](/2016/README.md) |
17-
|2015 |1-11 | - | [Link](/2015/) |[Link](/2015/README.md) |
17+
|2015 |1-12 | - | [Link](/2015/) |[Link](/2015/README.md) |
1818

1919
## To run ##
2020

0 commit comments

Comments
 (0)