<commit_before>#pragma once
#include <map>
#include <queue>
#include <functional>


namespace MX
{

	template<typename NodeType>
	class DijkstraPathFinding
	{
	public:
		using DistanceType = float;

		using NeighborCallback = std::function<void(const NodeType& node, DistanceType distance)>;
		using GetNeighborsFunc = std::function<void(const NodeType& node, const NeighborCallback& callback)>;

		using SetDistanceIfLowerFunc = std::function<bool(const NodeType& node, DistanceType distance)>;

		struct Functions
		{
			GetNeighborsFunc getNeighbors;
			SetDistanceIfLowerFunc setDistanceIfLower;
		};

		DijkstraPathFinding(const NodeType& start, const Functions& f)
		{
			_f = f;



			using Pair = std::pair<DistanceType, NodeType>;
			std::priority_queue<Pair, std::vector<Pair>, std::greater<Pair>> queue;

			
			DistanceType startDistance = 0.0f;
			queue.push(std::make_pair(startDistance, start));
			f.setDistanceIfLower(start, startDistance);


			while (!queue.empty())
			{
				auto p = queue.top();
				queue.pop();

				DistanceType current = p.first;


				auto forN = [&](const NodeType& node, DistanceType distance)
				{
					auto newDistance = current + distance;
					if (!f.setDistanceIfLower(node, newDistance))
						return;
					queue.push(std::make_pair(newDistance, node));

				};
				f.getNeighbors(p.second, forN);
			}

		}


	protected:
		Functions _f;


	};

	template<typename NodeType>
	class DefaultDijkstraPathFinding
	{
	public:
		using DijkstraPath = DijkstraPathFinding<NodeType>;
		using DistanceType = typename DijkstraPath::DistanceType;
		using GetNeighborsFunc = typename DijkstraPath::GetNeighborsFunc;
		using NeighborCallback = typename DijkstraPath::NeighborCallback;
		using MapType = std::map<NodeType, DistanceType>;

		DefaultDijkstraPathFinding(const NodeType& start, const GetNeighborsFunc& getNeighbors)
		{
			auto setDistanceIfLower = [&](const NodeType& node, DistanceType distance) -> bool
			{
				auto r = _distances.insert(std::make_pair(node, distance));
				if (r.second)
					return true;
				auto &old_pair = *(r.first);
				if (old_pair.second < distance)
					return false;

				old_pair.second = distance;
				return true;
			};


			typename DijkstraPath::Functions f;
			f.getNeighbors = getNeighbors;
			f.setDistanceIfLower = setDistanceIfLower;

			DijkstraPath Dijkstra(start, f);
		}

		const auto& distances() { return _distances; }
	protected:
		MapType _distances;
	};



}
<commit_msg>Allow range of start points in PathFInding.<commit_after>#pragma once
#include <map>
#include <queue>
#include <functional>


namespace MX
{

	template<typename NodeType>
	class DijkstraPathFinding
	{
	public:
		using DistanceType = float;

		using NeighborCallback = std::function<void(const NodeType& node, DistanceType distance)>;
		using GetNeighborsFunc = std::function<void(const NodeType& node, const NeighborCallback& callback)>;

		using SetDistanceIfLowerFunc = std::function<bool(const NodeType& node, DistanceType distance)>;

		using QueuePair = std::pair<DistanceType, NodeType>;
		using PriorityQueue = std::priority_queue<QueuePair, std::vector<QueuePair>, std::greater<QueuePair>>;

		struct Functions
		{
			GetNeighborsFunc getNeighbors;
			SetDistanceIfLowerFunc setDistanceIfLower;
		};

		DijkstraPathFinding(const std::vector<NodeType>& startNodes, const Functions& f)
		{
			PriorityQueue queue;

			DistanceType startDistance = 0.0f;
			for (auto& start : startNodes)
			{
				queue.push(std::make_pair(startDistance, start));
				f.setDistanceIfLower(start, startDistance);
			}

			PathFind(queue, f);
		}

		DijkstraPathFinding(const NodeType& start, const Functions& f)
		{
			PriorityQueue queue;

			DistanceType startDistance = 0.0f;
			queue.push(std::make_pair(startDistance, start));
			f.setDistanceIfLower(start, startDistance);

			PathFind(queue, f);
		}


	protected:
		void PathFind(PriorityQueue& queue, const Functions& f)
		{
			while (!queue.empty())
			{
				auto p = queue.top();
				queue.pop();

				DistanceType current = p.first;


				auto forN = [&](const NodeType& node, DistanceType distance)
				{
					auto newDistance = current + distance;
					if (!f.setDistanceIfLower(node, newDistance))
						return;
					queue.push(std::make_pair(newDistance, node));

				};
				f.getNeighbors(p.second, forN);
			}
		}
	};

	template<typename NodeType>
	class DefaultDijkstraPathFinding
	{
	public:
		using DijkstraPath = DijkstraPathFinding<NodeType>;
		using DistanceType = typename DijkstraPath::DistanceType;
		using GetNeighborsFunc = typename DijkstraPath::GetNeighborsFunc;
		using NeighborCallback = typename DijkstraPath::NeighborCallback;
		using MapType = std::map<NodeType, DistanceType>;

		DefaultDijkstraPathFinding(const NodeType& start, const GetNeighborsFunc& getNeighbors)
		{
			auto setDistanceIfLower = CreateCallback();
			typename DijkstraPath::Functions f;
			f.getNeighbors = getNeighbors;
			f.setDistanceIfLower = setDistanceIfLower;

			DijkstraPath Dijkstra(start, f);
		}

		DefaultDijkstraPathFinding(const std::vector<NodeType>& start, const GetNeighborsFunc& getNeighbors)
		{
			auto setDistanceIfLower = CreateCallback();
			typename DijkstraPath::Functions f;
			f.getNeighbors = getNeighbors;
			f.setDistanceIfLower = setDistanceIfLower;

			DijkstraPath Dijkstra(start, f);
		}

		const auto& distances() { return _distances; }
	protected:
		auto CreateCallback()
		{
			return [&](const NodeType& node, DistanceType distance) -> bool
			{
				auto r = _distances.insert(std::make_pair(node, distance));
				if (r.second)
					return true;
				auto &old_pair = *(r.first);
				if (old_pair.second < distance)
					return false;

				old_pair.second = distance;
				return true;
			};
		}

		MapType _distances;
	};



}

{'fraction_non_alphanumeric': 0.10676587644921266, 'fraction_numerical': 0.001038241910365115, 'mean_word_length': 4.381750465549349, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1425380', 'n_tokens_mistral': 2224, 'n_tokens_neox': 1811, 'n_words': 409}