1
Fork 0
This repository has been archived on 2025-04-09. You can view files and clone it, but cannot push or open issues or pull requests.
puzzle-wuzzle-generator/include/clusters.hpp
2014-02-04 20:00:21 +01:00

48 lines
1.2 KiB
C++

#pragma once
#include <cassert>
#include <set>
#include <boost/container/flat_set.hpp>
// Using boost flat set was faster than std::set.
namespace detail {
template <typename Field>
auto same_group(Field const & field, typename Field::Position const & p, typename Field::Position const & q){
return field.get(p) == field.get(q);
}
template <typename Field>
void cluster_expand(Field const & field, typename Field::Position const & p, boost::container::flat_set<typename Field::Position>& ret){
for(auto&& q : field.neighbors(p)){
if(!same_group(field, p, q)) continue;
if(ret.insert(q).second){
cluster_expand(field, q, ret);
}
}
}
}
template <typename Field>
auto cluster_at(Field const & field, typename Field::Position const & p){
boost::container::flat_set<typename Field::Position> ret;
ret.reserve(10); // speed improvement of 20%
ret.insert(p);
detail::cluster_expand(field, p, ret);
return ret;
}
template <typename Field>
auto all_clusters(Field const & field){
boost::container::flat_set<decltype(cluster_at(field, std::declval<typename Field::Position>()))> ret;
ret.reserve(10);
for(auto&& p : field.all_positions()){
if(field.empty(p)) continue;
ret.insert(cluster_at(field, p));
}
return ret;
}
#undef Set