diff --git a/include/clusters.hpp b/include/clusters.hpp index 4e98e42..5d9feda 100644 --- a/include/clusters.hpp +++ b/include/clusters.hpp @@ -16,42 +16,39 @@ auto make_empty(Field field, Cluster const & c){ } namespace detail { - template - auto same_group(Field const & field, typename Field::Position const & p, typename Field::Position const & q){ - return field.get(p) == field.get(q); - } - - template - void cluster_expand(Field const & field, typename Field::Position const & p, boost::container::flat_set& ret){ + template + void cluster_expand(Field const & field, Rules const & rules, typename Field::Position const & p, boost::container::flat_set& ret){ for(auto&& q : field.neighbors(p)){ - if(!same_group(field, p, q)) continue; + if(!rules.same_cluster(field.get(p), field.get(q))) continue; if(ret.insert(q).second){ - cluster_expand(field, q, ret); + cluster_expand(field, rules, q, ret); } } } } -template -auto cluster_at(Field const & field, typename Field::Position const & p){ +template +auto cluster_at(Field const & field, Rules const & rules, typename Field::Position const & p){ boost::container::flat_set ret; ret.reserve(10); // speed improvement of 20% ret.insert(p); - detail::cluster_expand(field, p, ret); + detail::cluster_expand(field, rules, p, ret); return ret; } template auto all_clusters(Grid const & grid, Rules const & rules){ - std::vector()))> ret; + std::vector()))> ret; ret.reserve(10); + auto partition = make_empty(grid, grid.all_positions()); auto current_p = 1; for(auto&& p : partition.all_positions()){ + // ignore if it already belongs to a cluster or is empty if(!partition.empty(p) || grid.empty(p)) continue; - auto cluster = cluster_at(grid, p); + auto cluster = cluster_at(grid, rules, p); for(auto&& q : cluster){ partition.get(q) = current_p; } diff --git a/include/rules.hpp b/include/rules.hpp index bf577c9..b46797d 100644 --- a/include/rules.hpp +++ b/include/rules.hpp @@ -9,6 +9,10 @@ struct BasicRules { return min_size; } + auto same_cluster(int x, int y) const { + return x == y; + } + private: unsigned int min_size; };