Skip to content

Commit 522fcfb

Browse files
authored
Add Minimum Spanning Tree in Ruby (#5946)
1 parent 697375e commit 522fcfb

1 file changed

Lines changed: 67 additions & 0 deletions

File tree

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# frozen_string_literal: true
2+
3+
USAGE = "Usage: please provide a comma-separated list of integers"
4+
5+
def usage!
6+
warn USAGE
7+
exit 1
8+
end
9+
10+
def parse_input
11+
raw = ARGV.first
12+
usage! if raw.nil? || raw.strip.empty?
13+
14+
nums = raw.split(",").map { Integer(it.strip) }
15+
n = Integer(Math.sqrt(nums.length))
16+
usage! unless n * n == nums.length
17+
18+
Array.new(n) { |i| nums[i * n, n] }
19+
rescue ArgumentError, NoMethodError
20+
usage!
21+
end
22+
23+
def find(parent, x)
24+
(parent[x] == x) ? x : (parent[x] = find(parent, parent[x]))
25+
end
26+
27+
def union(parent, rank, a, b)
28+
a = find(parent, a)
29+
b = find(parent, b)
30+
return if a == b
31+
32+
if rank[a] < rank[b]
33+
parent[a] = b
34+
elsif rank[a] > rank[b]
35+
parent[b] = a
36+
else
37+
parent[b] = a
38+
rank[a] += 1
39+
end
40+
end
41+
42+
def mst_weight(matrix)
43+
n = matrix.size
44+
45+
edges =
46+
(0...n).flat_map do |i|
47+
(i + 1...n).map do |j|
48+
w = matrix[i][j]
49+
w.positive? ? [w, i, j] : nil
50+
end
51+
end.compact
52+
53+
edges.sort_by!(&:first)
54+
55+
parent = (0...n).to_a
56+
rank = Array.new(n, 0)
57+
58+
edges.reduce(0) do |total, (w, u, v)|
59+
next total if find(parent, u) == find(parent, v)
60+
61+
union(parent, rank, u, v)
62+
total + w
63+
end
64+
end
65+
66+
matrix = parse_input
67+
puts mst_weight(matrix)

0 commit comments

Comments
 (0)