File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 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 )
You can’t perform that action at this time.
0 commit comments