\$\begingroup\$
\$\endgroup\$
2
It is a set of edges of a graph given. An edge is given as an array of its endpoints, e.g. [:a, :b]
. The array can contain an arbitrary amount of endpoints. Therefore []
and [:b, :c, :d]
are also valid edges.
I want to find all islands which means that I looking for unconnected sets of nodes. Here is my Ruby solution.
e = [[:a, :b],[:c, :d],[:b, :c, :e], [:f, :g]]
n = e.flatten.uniq
def islands(edges)
edges.reduce([]) do |islands, edge|
matches = islands.select { |island| island.any? { |node| edge.include?(node) } }
if !matches.empty?
island = matches.shift
islands.delete_if { |i| matches.include?(i) }
island.concat(matches.flatten)
island.concat(edge)
island.uniq!
else
islands << edge
end
islands
end
end
puts islands(e).inspect
# => [[:a, :b, :c, :d, :e], [:f, :g]]
Is there room for improvement?
asked Aug 5, 2015 at 7:53
-
\$\begingroup\$ Found a similar question for C# \$\endgroup\$sschmeck– sschmeck2015年08月05日 08:31:22 +00:00Commented Aug 5, 2015 at 8:31
-
\$\begingroup\$ I am too lazy to write an answer, but with a quick-union algorithm it would be much, much faster. cs.princeton.edu/~rs/AlgsDS07/01UnionFind.pdf \$\endgroup\$tokland– tokland2015年08月05日 16:36:03 +00:00Commented Aug 5, 2015 at 16:36
1 Answer 1
\$\begingroup\$
\$\endgroup\$
1
if !matches.empty?
equals
if matches.any?
And the second is preferable, cause you don't have negation.
-
\$\begingroup\$ [nil].empty? == [nil].any? \$\endgroup\$Nakilon– Nakilon2015年08月06日 20:03:30 +00:00Commented Aug 6, 2015 at 20:03
lang-rb