Unable to load image

day 16 aoc thread: the np is complete

this is travelling salesmen, eh? i'm pretty sure at least.

14
Jump in the discussion.

No email address required.

Well after a lot of time trying to find the bug, i realized that we are always supposed to start at 'AA', but instead i started at the first line of the input. Literally would have been done like after like 30 minutes if I had paid attention to that...

I solve part two simply by dfs through the part once, and then if time gets to zero, i restart the dfs.

Part one ran in 661ms, Part two in 38004ms. Could most likely really speed this up by turning nodes with a flow rate of 0, into longer tunnels, but really don't care anymore.


#include <iostream>
#include <vector>
#include <utility>
#include <tuple>
#include <unordered_map>
#include <map>
#include <format>
#include <chrono>

struct input_set {
	std::vector<int64_t> flow_rates;
	std::vector<std::vector<int64_t>> tunnels;
};

input_set test_set{
	{ 0, 13, 2, 20, 3, 0, 0, 22, 0, 21 },
	{{3,8,1},{2,0},{3,1},{2,0,4},{5,3},{4,6},{5,7},{6},{0,9},{8}} 
};

input_set real_set{
	{0,0,0,0,0,0,0,19,0,0,0,0,24,7,6,8,18,14,0,0,0,0,0,0,12,0,0,0,0,0,0,0,4,0,0,0,11,17,0,0,0,0,0,0,0,0,23,0,0,16,5,0,0,0,0,15},
	{{49,14},{55,47},{12,6},{45,24},{46,41},{13,34},{2,49},{22,40},{35,13},{48,24},{36,32},{50,28},{2},{21,5,51,8,27},{18,19,0,42,30},{38,34,52,20},{22},{41,54},{50,14},{32,14},{15,36},{53,13},{7,16},{49,38},{3,52,9,39},{31,55},{32,27},{13,26},{11,53},{44,50},{14,53},{37,25},{43,10,44,19,26},{36,39},{5,15},{8,50},{20,10,33,47},{40,31},{15,23},{33,24},{37,7},{17,4},{51,14},{53,32},{32,29},{3,55},{4},{1,36},{53,9},{23,0,6},{54,18,35,11,29},{42,13},{15,24},{43,21,48,28,30},{50,17},{45,25,1}}
};

typedef std::tuple<int64_t, int64_t, int64_t, int64_t> key_type;
typedef std::map<key_type, int64_t> map_type;

int64_t dfs(int64_t location, int64_t time, int64_t turned_on, map_type& dp, const input_set& input, int runs) {
	key_type key = std::make_tuple(runs, location, time, turned_on);
	if (dp.count(key) == 1) return dp[key];

	if (time < 1) {
		if (runs > 1) return dfs(53, 26, turned_on, dp, input, runs - 1);
		else return 0LL;
	}

	auto rate = input.flow_rates[location];
	int64_t ans{0};
	// turned on is a a bitmap with a 1 at bit location, if location is turned
	// we are checking if it is not turned on
	if ((turned_on & (1LL << location)) == 0 && rate > 0) {
		int64_t turned_on_new = turned_on + (1LL << location);
		ans = (time - 1) * rate + dfs(location, time - 1, turned_on_new, dp, input, runs);
	}
	for (auto next_location : input.tunnels[location]) {
		ans = std::max(dfs(next_location, time - 1, turned_on, dp, input, runs), ans);
	}

	dp[key] = ans;
	return ans;	
}

int main()
{
	map_type dp_test;
	map_type dp;
	map_type dp_p2;

	auto a = std::chrono::high_resolution_clock::now();
	std::cout << "Test:" << dfs(0, 30, 0, dp_test, test_set, 1) << '\n';
	auto b = std::chrono::high_resolution_clock::now();
	std::cout << "Part One:" << dfs(53, 30, 0, dp, real_set, 1) << '\n';
	auto c = std::chrono::high_resolution_clock::now();
	std::cout << "Part Two:" << dfs(53, 26, 0, dp_p2, real_set, 2) << '\n';
	auto d = std::chrono::high_resolution_clock::now();

	auto ba = std::chrono::duration_cast<std::chrono::microseconds>(b - a);
	auto cb = std::chrono::duration_cast<std::chrono::microseconds>(c - b);
	auto dc = std::chrono::duration_cast<std::chrono::microseconds>(d - c);

	std::cout << std::format("TIMES: TEST: {}ms PART ONE: {}ms PART TWO: {}ms", ba, cb, dc);
}


Jump in the discussion.

No email address required.

Mommy is soooo proud of you, sweaty. Let's put this sperg out up on the fridge with all your other failures.

Jump in the discussion.

No email address required.

Well after a lot of time trying to find the bug, i realized that we are always supposed to start at 'AA', but instead i started at the first line of the input. Literally would have been done like after like 30 minutes if I had paid attention to that...

LMAO same. Though I got lucky in that the thing told me that my answer is too high, so it must've been a bug and not a wrong algorithm, and I was lowkey bothered by writing the code that extracted starting node name from the first node without an explicit instruction to do so, so it was on my mind, so I immediately reread the task and oh shit.

I solve part two simply by running it in serial, apparently that gives the same result as if they were ran in parallel.

Neat!

Jump in the discussion.

No email address required.

Link copied to clipboard
Action successful!
Error, please refresh the page and try again.