aboutsummaryrefslogtreecommitdiff
path: root/2015
diff options
context:
space:
mode:
Diffstat (limited to '2015')
-rw-r--r--2015/src/day12.cpp78
-rw-r--r--2015/src/day13.cpp108
-rw-r--r--2015/src/day14.cpp112
3 files changed, 298 insertions, 0 deletions
diff --git a/2015/src/day12.cpp b/2015/src/day12.cpp
new file mode 100644
index 0000000..2bb2e78
--- /dev/null
+++ b/2015/src/day12.cpp
@@ -0,0 +1,78 @@
1#include <fstream>
2#include <iostream>
3#include <iterator>
4#include <string>
5
6// JSON parsing
7#include <nlohmann/json.hpp>
8
9using namespace std;
10using json = nlohmann::json;
11
12string
13read_file(string_view filename)
14{
15 fstream input{ filename };
16 return { istreambuf_iterator{ input }, {} };
17}
18
19template<class UnaryFunction>
20void
21recursive_iterate(const json& j, UnaryFunction f) // NOLINT
22{
23 for ( auto it = j.begin(); it != j.end(); ++it ) {
24 if ( it->is_structured() ) {
25 recursive_iterate(*it, f);
26 }
27 else {
28 f(it);
29 }
30 }
31}
32
33void
34part1(string_view document)
35{
36 auto json = json::parse(document);
37
38 long sum = 0;
39 recursive_iterate(json, [&](json::const_iterator iter) {
40 if ( iter.value().is_number() ) {
41 sum += iter.value().get<long>();
42 }
43 });
44 cout << sum << endl;
45}
46
47void
48part2(string_view document)
49{
50 json::parser_callback_t parser_callback = [](int /*depth*/, json::parse_event_t event, json& parsed) {
51 if ( event == json::parse_event_t::object_end ) {
52 for ( auto it = parsed.begin(); it != parsed.end(); ++it ) {
53 if ( it.value().is_string() && it.value().get<string>() == "red" ) {
54 return false;
55 }
56 }
57 }
58 return true;
59 };
60
61 auto json = json::parse(document, parser_callback);
62
63 long sum = 0;
64 recursive_iterate(json, [&](json::const_iterator iter) {
65 if ( iter.value().is_number() ) {
66 sum += iter.value().get<long>();
67 }
68 });
69 cout << sum << endl;
70}
71
72int
73main()
74{
75 auto document = read_file("data/day12.txt");
76 part1(document);
77 part2(document);
78}
diff --git a/2015/src/day13.cpp b/2015/src/day13.cpp
new file mode 100644
index 0000000..7256b81
--- /dev/null
+++ b/2015/src/day13.cpp
@@ -0,0 +1,108 @@
1#include <algorithm>
2#include <fstream>
3#include <iostream>
4#include <iterator>
5#include <limits>
6#include <map>
7#include <set>
8#include <sstream>
9#include <string>
10#include <tuple>
11#include <vector>
12
13using namespace std;
14
15auto
16split(const string& line, char sep = ' ')
17{
18 vector<string> parts;
19 stringstream input{ line };
20
21 for ( string part; getline(input, part, sep); ) {
22 parts.emplace_back(part);
23 }
24
25 return parts;
26}
27
28auto
29read_file(string_view filename)
30{
31 fstream input{ filename };
32 set<string> names;
33 map<tuple<string, string>, long> table;
34
35 for ( string line; getline(input, line); ) {
36 if ( line.ends_with(".") ) {
37 line.pop_back();
38 }
39
40 auto parts = split(line);
41
42 auto start = parts[0];
43 auto units = parts[2] == "gain" ? stol(parts[3]) : -stol(parts[3]);
44 auto end = parts[10]; // NOLINT
45
46 table[{ start, end }] = units;
47
48 names.insert(start);
49 }
50 return table;
51}
52
53void
54part1(map<tuple<string, string>, long>& table)
55{
56 set<string> unique_names;
57 for ( const auto& item: table ) {
58 unique_names.insert(get<0>(item.first));
59 }
60 vector<string> names{ begin(unique_names), end(unique_names) };
61
62 long happiness_sofar = numeric_limits<long>::min();
63 do {
64 long happiness = 0;
65 for ( size_t idx = 0; idx != names.size(); ++idx ) {
66 auto next_idx = (idx + 1) % names.size();
67
68 happiness += table[{ names[idx], names[next_idx] }];
69 happiness += table[{ names[next_idx], names[idx] }];
70 }
71
72 happiness_sofar = max(happiness_sofar, happiness);
73 } while ( next_permutation(begin(names), end(names)) );
74 cout << happiness_sofar << endl;
75}
76
77void
78part2(map<tuple<string, string>, long>& table)
79{
80 set<string> unique_names;
81 for ( const auto& item: table ) {
82 unique_names.insert(get<0>(item.first));
83 }
84 vector<string> names{ begin(unique_names), end(unique_names) };
85 names.emplace_back("Hartkode");
86
87 long happiness_sofar = numeric_limits<long>::min();
88 do {
89 long happiness = 0;
90 for ( size_t idx = 0; idx != names.size(); ++idx ) {
91 auto next_idx = (idx + 1) % names.size();
92
93 happiness += table[{ names[idx], names[next_idx] }];
94 happiness += table[{ names[next_idx], names[idx] }];
95 }
96
97 happiness_sofar = max(happiness_sofar, happiness);
98 } while ( next_permutation(begin(names), end(names)) );
99 cout << happiness_sofar << endl;
100}
101
102int
103main()
104{
105 auto table = read_file("data/day13.txt");
106 part1(table);
107 part2(table);
108}
diff --git a/2015/src/day14.cpp b/2015/src/day14.cpp
new file mode 100644
index 0000000..a877630
--- /dev/null
+++ b/2015/src/day14.cpp
@@ -0,0 +1,112 @@
1#include <fstream>
2#include <iostream>
3#include <limits>
4#include <map>
5#include <sstream>
6#include <string>
7#include <tuple>
8#include <vector>
9using namespace std;
10
11using record_type = tuple<string, long, long, long>;
12
13auto
14split(const string& line, char sep = ' ')
15{
16 vector<string> parts;
17 stringstream input{ line };
18
19 for ( string part; getline(input, part, sep); ) {
20 parts.emplace_back(part);
21 }
22
23 return parts;
24}
25
26auto
27read_file(string_view filename)
28{
29 fstream input{ filename };
30 vector<record_type> records;
31
32 for ( string line; getline(input, line); ) {
33 auto parts = split(line);
34 records.emplace_back(parts[0], stol(parts[3]), stol(parts[6]), stol(parts[13])); // NOLINT
35 }
36 return records;
37}
38
39static const size_t max_seconds = 2503;
40
41map<string, vector<long>>
42calculate_distances(const vector<record_type>& records)
43{
44 map<string, vector<long>> distances;
45
46 for ( const auto& [name, speed, sec, sec2]: records ) {
47 long distance = 0;
48 for ( size_t second = 0; second != max_seconds; ) {
49 for ( size_t i = 0; second != max_seconds && i != (size_t) sec; ++i ) {
50 distance += speed;
51 ++second;
52 distances[name].emplace_back(distance);
53 }
54 for ( long i = 0; second != max_seconds && i != sec2; ++i ) {
55 ++second;
56 distances[name].emplace_back(distance);
57 }
58 }
59 }
60 return distances;
61}
62
63void
64part1(const vector<record_type>& records)
65{
66 auto distances = calculate_distances(records);
67 long distance = numeric_limits<long>::min();
68
69 for ( const auto& record: records ) {
70 auto name = get<0>(record);
71 auto final_distance = distances[name].back();
72 distance = max(distance, final_distance);
73 }
74
75 cout << distance << endl;
76}
77
78void
79part2(const vector<record_type>& records)
80{
81 auto distances = calculate_distances(records);
82
83 map<string, long> points;
84 for ( size_t second = 0; second != max_seconds; ++second ) {
85 auto max_distance = numeric_limits<long>::min();
86 for ( const auto& record: records ) {
87 auto name = get<0>(record);
88 max_distance = max(max_distance, distances[name][second]);
89 }
90
91 for ( const auto& record: records ) {
92 auto name = get<0>(record);
93 if ( distances[name][second] == max_distance ) {
94 ++points[name];
95 }
96 }
97 }
98
99 auto max_points = numeric_limits<long>::min();
100 for ( const auto& [name, points]: points ) {
101 max_points = max(max_points, points);
102 }
103 cout << max_points << endl;
104}
105
106int
107main()
108{
109 auto records = read_file("data/day14.txt");
110 part1(records);
111 part2(records);
112}