From 566dbf51f27b6e181826b8de6c1cb98b4a680fe8 Mon Sep 17 00:00:00 2001 From: Thomas Schmucker Date: Fri, 15 Nov 2024 16:57:33 +0100 Subject: aoc 2015, days 12, 13 and 14 --- 2015/src/day12.cpp | 78 +++++++++++++++++++++++++++++++++++++ 2015/src/day13.cpp | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2015/src/day14.cpp | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 298 insertions(+) create mode 100644 2015/src/day12.cpp create mode 100644 2015/src/day13.cpp create mode 100644 2015/src/day14.cpp (limited to '2015') 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 @@ +#include +#include +#include +#include + +// JSON parsing +#include + +using namespace std; +using json = nlohmann::json; + +string +read_file(string_view filename) +{ + fstream input{ filename }; + return { istreambuf_iterator{ input }, {} }; +} + +template +void +recursive_iterate(const json& j, UnaryFunction f) // NOLINT +{ + for ( auto it = j.begin(); it != j.end(); ++it ) { + if ( it->is_structured() ) { + recursive_iterate(*it, f); + } + else { + f(it); + } + } +} + +void +part1(string_view document) +{ + auto json = json::parse(document); + + long sum = 0; + recursive_iterate(json, [&](json::const_iterator iter) { + if ( iter.value().is_number() ) { + sum += iter.value().get(); + } + }); + cout << sum << endl; +} + +void +part2(string_view document) +{ + json::parser_callback_t parser_callback = [](int /*depth*/, json::parse_event_t event, json& parsed) { + if ( event == json::parse_event_t::object_end ) { + for ( auto it = parsed.begin(); it != parsed.end(); ++it ) { + if ( it.value().is_string() && it.value().get() == "red" ) { + return false; + } + } + } + return true; + }; + + auto json = json::parse(document, parser_callback); + + long sum = 0; + recursive_iterate(json, [&](json::const_iterator iter) { + if ( iter.value().is_number() ) { + sum += iter.value().get(); + } + }); + cout << sum << endl; +} + +int +main() +{ + auto document = read_file("data/day12.txt"); + part1(document); + part2(document); +} 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 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +auto +split(const string& line, char sep = ' ') +{ + vector parts; + stringstream input{ line }; + + for ( string part; getline(input, part, sep); ) { + parts.emplace_back(part); + } + + return parts; +} + +auto +read_file(string_view filename) +{ + fstream input{ filename }; + set names; + map, long> table; + + for ( string line; getline(input, line); ) { + if ( line.ends_with(".") ) { + line.pop_back(); + } + + auto parts = split(line); + + auto start = parts[0]; + auto units = parts[2] == "gain" ? stol(parts[3]) : -stol(parts[3]); + auto end = parts[10]; // NOLINT + + table[{ start, end }] = units; + + names.insert(start); + } + return table; +} + +void +part1(map, long>& table) +{ + set unique_names; + for ( const auto& item: table ) { + unique_names.insert(get<0>(item.first)); + } + vector names{ begin(unique_names), end(unique_names) }; + + long happiness_sofar = numeric_limits::min(); + do { + long happiness = 0; + for ( size_t idx = 0; idx != names.size(); ++idx ) { + auto next_idx = (idx + 1) % names.size(); + + happiness += table[{ names[idx], names[next_idx] }]; + happiness += table[{ names[next_idx], names[idx] }]; + } + + happiness_sofar = max(happiness_sofar, happiness); + } while ( next_permutation(begin(names), end(names)) ); + cout << happiness_sofar << endl; +} + +void +part2(map, long>& table) +{ + set unique_names; + for ( const auto& item: table ) { + unique_names.insert(get<0>(item.first)); + } + vector names{ begin(unique_names), end(unique_names) }; + names.emplace_back("Hartkode"); + + long happiness_sofar = numeric_limits::min(); + do { + long happiness = 0; + for ( size_t idx = 0; idx != names.size(); ++idx ) { + auto next_idx = (idx + 1) % names.size(); + + happiness += table[{ names[idx], names[next_idx] }]; + happiness += table[{ names[next_idx], names[idx] }]; + } + + happiness_sofar = max(happiness_sofar, happiness); + } while ( next_permutation(begin(names), end(names)) ); + cout << happiness_sofar << endl; +} + +int +main() +{ + auto table = read_file("data/day13.txt"); + part1(table); + part2(table); +} 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 @@ +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +using record_type = tuple; + +auto +split(const string& line, char sep = ' ') +{ + vector parts; + stringstream input{ line }; + + for ( string part; getline(input, part, sep); ) { + parts.emplace_back(part); + } + + return parts; +} + +auto +read_file(string_view filename) +{ + fstream input{ filename }; + vector records; + + for ( string line; getline(input, line); ) { + auto parts = split(line); + records.emplace_back(parts[0], stol(parts[3]), stol(parts[6]), stol(parts[13])); // NOLINT + } + return records; +} + +static const size_t max_seconds = 2503; + +map> +calculate_distances(const vector& records) +{ + map> distances; + + for ( const auto& [name, speed, sec, sec2]: records ) { + long distance = 0; + for ( size_t second = 0; second != max_seconds; ) { + for ( size_t i = 0; second != max_seconds && i != (size_t) sec; ++i ) { + distance += speed; + ++second; + distances[name].emplace_back(distance); + } + for ( long i = 0; second != max_seconds && i != sec2; ++i ) { + ++second; + distances[name].emplace_back(distance); + } + } + } + return distances; +} + +void +part1(const vector& records) +{ + auto distances = calculate_distances(records); + long distance = numeric_limits::min(); + + for ( const auto& record: records ) { + auto name = get<0>(record); + auto final_distance = distances[name].back(); + distance = max(distance, final_distance); + } + + cout << distance << endl; +} + +void +part2(const vector& records) +{ + auto distances = calculate_distances(records); + + map points; + for ( size_t second = 0; second != max_seconds; ++second ) { + auto max_distance = numeric_limits::min(); + for ( const auto& record: records ) { + auto name = get<0>(record); + max_distance = max(max_distance, distances[name][second]); + } + + for ( const auto& record: records ) { + auto name = get<0>(record); + if ( distances[name][second] == max_distance ) { + ++points[name]; + } + } + } + + auto max_points = numeric_limits::min(); + for ( const auto& [name, points]: points ) { + max_points = max(max_points, points); + } + cout << max_points << endl; +} + +int +main() +{ + auto records = read_file("data/day14.txt"); + part1(records); + part2(records); +} -- cgit v1.3