Unable to load image

Day 12

Post code, nerds.

14
Jump in the discussion.

No email address required.

spent some time thinking of proper algorithm that can handle multiple sources or targets, but then gave up. You could most likely use djikstra to start at the end point, calculate the distance to every node and the pick the starting nodes with the lowest distance. Instead of just doing a BFS from every starting node to the End Node. But why would i implement that one manually and people that use library algorithm are :marseyyikes:.


#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <utility>
#include <queue>
#include <array>

typedef std::pair<int32_t, int32_t> coordinate;

constexpr char max_char = 'z';

int32_t run(std::vector<std::vector<char>>& map, std::vector<coordinate>& start_points) {
	std::array<int32_t, 4> dirx{ 0,0,1,-1 };
	std::array<int32_t, 4> diry{ 1,-1,0, 0 };

	size_t RR = map.size();
	size_t CC = map[0].size();
	int32_t shortest_distance = INT32_MAX;

	for (auto start : start_points) {
		std::vector<std::vector<int32_t>> dist(RR, std::vector<int32_t>(CC));
		for (auto& row : dist) std::fill(row.begin(), row.end(), -1);

		std::queue<coordinate> q;
		q.push(start);
		dist[start.first][start.second] = 0;
		while (!q.empty()) {
			auto p = q.front();
			q.pop();
			char current = map[p.first][p.second];
			if (current == 'S') current = 'a';
			for (size_t i{ 0 }; i < 4; i++) {
				int y = p.first + diry[i];
				int x = p.second + dirx[i];
				if (y >= 0 && x >= 0 && y < RR && x < CC && dist[y][x] == -1 &&
					(
						(map[y][x] != 'E' && map[y][x] - current <= 1) ||
						(map[y][x] == 'E' && current == max_char)
						)) {
					dist[y][x] = 1 + dist[p.first][p.second];
					if (map[y][x] == 'E') shortest_distance = std::min(dist[y][x], shortest_distance);
					q.push(std::make_pair(y, x));
				}
			}
		}
	}

	return shortest_distance;

}

int main() {
	std::ifstream file("input.txt");
	std::string buf;
	std::vector<std::vector<char>> map;
	std::vector<coordinate> partOne_starts;
	std::vector<coordinate> partTwo_starts;

	size_t c_y = 0;
	while (std::getline(file, buf)) {
		map.push_back({});
		size_t c_x = 0;
		for (char c : buf) {
			if (c == 'S') partOne_starts.push_back(std::make_pair(c_y, c_x));
			if (c == 'S' || c == 'a') partTwo_starts.push_back(std::make_pair(c_y, c_x));
			map.back().push_back(c);
			++c_x;
		}
		++c_y;
	}
	std::cout << "Part One: " << run(map, partOne_starts) << '\n';
	std::cout << "Part Two: " << run(map, partTwo_starts) << '\n';
	return -1;
}

Jump in the discussion.

No email address required.

or actually you can just start at the end and BFS your way until you find the first a, that will automatically be the closest.

i think performance wise best would be A* search with manhattan distance as a heuristic

Jump in the discussion.

No email address required.

>people that use library algorithm are :marseyyikes:

cope and seethe, slowcel :marseysmug2:

Jump in the discussion.

No email address required.

>djikstra to start at the end point

Thanks, that's what I missed. I did the BIPOC solution of just slapping a for loop and it werks but I knew that was not good.

I also need to fix a bug with my makeshift priority queue because it works when I use it in reverse but not in the right way, regardless of the sorting.

Jump in the discussion.

No email address required.

Sorry ma'am, looks like his delusions have gotten worse. We'll have to admit him.

Jump in the discussion.

No email address required.

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