union_find 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +24 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +72 -0
- data/Rakefile +2 -0
- data/lib/union_find/version.rb +3 -0
- data/lib/union_find.rb +106 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/union_find_spec.rb +119 -0
- data/union_find.gemspec +25 -0
- metadata +114 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3d86fb59ebdb3b6b5f55e175db95bd7dccf0126b
|
4
|
+
data.tar.gz: 8dfbcfdff8f2a1f20e808df6404312bbd2793967
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fee3e76ee13f5c64e8b8f278e8c42ac0ebb979603bc3b1e19b4e76980ba8128c9c1fd594c31d04006f61149afbf86b364cd71d0f59a2206aa7140d3350f13096
|
7
|
+
data.tar.gz: 280542a0d35dc79eb7343f3efd350e8ea8629a47377cb9b04ae58076b9e3da45f983ffa5ce522518515bbef974746a097b16dfd8b87db09f8b93bbb1928b98b5
|
data/.gitignore
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
23
|
+
.ruby-gemset
|
24
|
+
.ruby-version
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Michael Imstepf
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
# Weighted quick-union algorithm with path compression
|
2
|
+
|
3
|
+
Union Find is an algorithm that uses a disjoint-set data structure. It allows us to efficiently connect any items of a given list and to efficiently check whether two items of this list are connected (any degree of separation) or not.
|
4
|
+
|
5
|
+
Possible applications where we might want to find out whether two items are connected to each other are:
|
6
|
+
* Social networks
|
7
|
+
* Computers in a network
|
8
|
+
* Web pages on the Internet
|
9
|
+
* Transistors in a computer chip
|
10
|
+
* Pixels in a digital photo
|
11
|
+
* Metallic sites in a composite system
|
12
|
+
|
13
|
+
Click [here](https://www.cs.princeton.edu/~rs/AlgsDS07/01UnionFind.pdf) for more information.
|
14
|
+
|
15
|
+
The running time of this algorithm is linear.
|
16
|
+
|
17
|
+
This a Ruby implementation of [Robert Sedgewick](http://www.cs.princeton.edu/~rs/)'s and [Kevin Wayne](http://www.cs.princeton.edu/~wayne/contact/)'s [weighted quick-union algorithm with path compression](http://algs4.cs.princeton.edu/15uf/UF.java.html). Credit goes to these two authors of the book [Algorithms](http://www.amazon.com/gp/product/032157351X/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&tag=algs4-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=032157351X) and to the many computer scientists that have contributed to this algorithm in the past decades.
|
18
|
+
|
19
|
+
## Installation
|
20
|
+
|
21
|
+
Add this line to your application's Gemfile:
|
22
|
+
|
23
|
+
gem 'union_find'
|
24
|
+
|
25
|
+
And then execute:
|
26
|
+
|
27
|
+
$ bundle
|
28
|
+
|
29
|
+
Or install it yourself as:
|
30
|
+
|
31
|
+
$ gem install union_find
|
32
|
+
|
33
|
+
## Usage
|
34
|
+
|
35
|
+
Create a new instance of `UnionFind` and pass in an array of items:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
union_find = UnionFind::UnionFind.new(['Grandfather', 'Father', 'Daughter', 'Single Person'])
|
39
|
+
```
|
40
|
+
|
41
|
+
Connect items (in any order):
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
union_find.union('Grandfather', 'Father')
|
45
|
+
union_find.union('Father', 'Daughter')
|
46
|
+
```
|
47
|
+
|
48
|
+
Check whether two items are connected (in any order):
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
union_find.connected?('Grandfather', 'Daughter')
|
52
|
+
=> true
|
53
|
+
union_find.connected?('Daughter', 'Father')
|
54
|
+
=> true
|
55
|
+
union_find.connected?('Grandfather', 'Single Person')
|
56
|
+
=> false
|
57
|
+
```
|
58
|
+
|
59
|
+
Check how many isolated items there are. In this example, there are 2, namely the family the family tree (Grandfather - Father - Daugther) and the Single Person:
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
union_find.count_isolated_components
|
63
|
+
=> 2
|
64
|
+
```
|
65
|
+
|
66
|
+
## Contributing
|
67
|
+
|
68
|
+
1. Fork it ( https://github.com/[my-github-username]/union_find/fork )
|
69
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
70
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
71
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
72
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/lib/union_find.rb
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'union_find/version'
|
2
|
+
|
3
|
+
module UnionFind
|
4
|
+
|
5
|
+
# The UnionFind class represents a union-find data type
|
6
|
+
# (also known as the disjoint-sets data type).
|
7
|
+
# It supports the union and find operations,
|
8
|
+
# along with a connected operation for determinig whether
|
9
|
+
# two sites in the same component are connected and a count operation that
|
10
|
+
# returns the total number of components.
|
11
|
+
|
12
|
+
# This implementation uses weighted quick union by rank with path compression
|
13
|
+
# by halving.
|
14
|
+
|
15
|
+
# Initializing a data structure with number_of_components sites takes linear time.
|
16
|
+
# Afterwards, the union, find, and connected
|
17
|
+
# operations take logarithmic time (in the worst case) and the
|
18
|
+
# count operation takes constant time.
|
19
|
+
|
20
|
+
# @author Robert Sedgewick
|
21
|
+
# @author Kevin Wayne
|
22
|
+
# @author Michael Imstepf
|
23
|
+
# @see http://algs4.cs.princeton.edu/15uf/UF.java.html
|
24
|
+
# @see http://algs4.cs.princeton.edu/15uf/
|
25
|
+
class UnionFind
|
26
|
+
|
27
|
+
# Initializes an empty union-find data structure with
|
28
|
+
# n isolated components 0 through n-1.
|
29
|
+
# @param components [Array] components
|
30
|
+
# @raise [ArgumentError] if components.length < 1 or if components is not an Array
|
31
|
+
def initialize(components)
|
32
|
+
raise ArgumentError, 'input is not an Array' unless components.class == Array
|
33
|
+
|
34
|
+
components = components.uniq # remove duplicates
|
35
|
+
@number_of_isolated_components = components.length
|
36
|
+
|
37
|
+
raise ArgumentError, 'number of components is < 1' if @number_of_isolated_components < 1
|
38
|
+
|
39
|
+
@parent = {} # parent of i
|
40
|
+
@tree_size = {} # size of tree rooted at i (cannot be more than 31)
|
41
|
+
components.each do |component|
|
42
|
+
@parent[component] = component
|
43
|
+
@tree_size[component] = 1
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns the number of isolated components.
|
48
|
+
# @return [Interger] the number of components
|
49
|
+
def count_isolated_components
|
50
|
+
@number_of_isolated_components
|
51
|
+
end
|
52
|
+
|
53
|
+
# Returns the root of a component.
|
54
|
+
# @param component_id [Integer] the integer representing one component
|
55
|
+
# @return [Component] the root of the component
|
56
|
+
# @raise [IndexError] unless component exists
|
57
|
+
def find_root(component)
|
58
|
+
raise IndexError, 'component does not exist' unless @parent[component]
|
59
|
+
|
60
|
+
while component != @parent[component] # stop at the top node where component id == parent id
|
61
|
+
@parent[component] = @parent[@parent[component]] # path compression by halving
|
62
|
+
component = @parent[component]
|
63
|
+
end
|
64
|
+
|
65
|
+
return component
|
66
|
+
end
|
67
|
+
|
68
|
+
# Connect root of component 1 with root of component 2
|
69
|
+
# by attaching smaller subtree root node with larger tree.
|
70
|
+
# If both trees have the same size, the root of the second
|
71
|
+
# component becomes a child of the root of the first component.
|
72
|
+
# @param component_1_id [Integer] the integer representing one component
|
73
|
+
# @param component_2_id [Integer] the integer representing the other component
|
74
|
+
# @return [Component, NilClass] the root of the larger tree or the root of the first component if both have the same tree size or nil if no connection has been made
|
75
|
+
def union(component_1, component_2)
|
76
|
+
root_component_1 = find_root(component_1)
|
77
|
+
root_component_2 = find_root(component_2)
|
78
|
+
|
79
|
+
return nil if root_component_1 == root_component_2
|
80
|
+
|
81
|
+
# make smaller root point to larger one
|
82
|
+
if @tree_size[root_component_1] < @tree_size[root_component_2]
|
83
|
+
@parent[root_component_1] = root_component_2
|
84
|
+
root = root_component_2
|
85
|
+
@tree_size[root_component_2] += @tree_size[root_component_1]
|
86
|
+
else
|
87
|
+
@parent[root_component_2] = root_component_1
|
88
|
+
root = root_component_1
|
89
|
+
@tree_size[root_component_1] += @tree_size[root_component_2]
|
90
|
+
end
|
91
|
+
|
92
|
+
@number_of_isolated_components -= 1
|
93
|
+
|
94
|
+
root
|
95
|
+
end
|
96
|
+
|
97
|
+
# Do two components share the same root?
|
98
|
+
# @param component_1 [Integer] the integer representing one component
|
99
|
+
# @param component_2 [Integer] the integer representing the other component
|
100
|
+
# @return [Boolean]
|
101
|
+
def connected?(component_1, component_2)
|
102
|
+
find_root(component_1) == find_root(component_2)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'union_find'
|
2
|
+
require 'pry' # to use binding.pry
|
3
|
+
|
4
|
+
RSpec.configure do |config|
|
5
|
+
# Run specs in random order to surface order dependencies. If you find an
|
6
|
+
# order dependency and want to debug it, you can fix the order by providing
|
7
|
+
# the seed, which is printed after each run.
|
8
|
+
# --seed 1234
|
9
|
+
config.order = 'random'
|
10
|
+
|
11
|
+
# when a focus tag is present in RSpec, only run tests with focus tag: http://railscasts.com/episodes/285-spork
|
12
|
+
config.filter_run focus: true
|
13
|
+
config.run_all_when_everything_filtered = true
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_family_tree(union_find)
|
17
|
+
union_find.union('Grandfather', 'Father')
|
18
|
+
union_find.union('Grandfather', 'Mother')
|
19
|
+
union_find.union('Mother', 'Son')
|
20
|
+
union_find.union('Father', 'Daughter')
|
21
|
+
|
22
|
+
union_find
|
23
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
random = Random.new
|
3
|
+
|
4
|
+
describe UnionFind::UnionFind do
|
5
|
+
# 1 family and 1 single person
|
6
|
+
people = ['Grandfather', 'Father', 'Mother', 'Son', 'Daughter', 'Single']
|
7
|
+
|
8
|
+
describe '#initialize' do
|
9
|
+
context 'when no components are provided' do
|
10
|
+
it 'raises an exception' do
|
11
|
+
expect {UnionFind::UnionFind.new()}.to raise_exception(ArgumentError)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'when components in form other than Array are provided' do
|
16
|
+
it 'raises an exception' do
|
17
|
+
expect {UnionFind::UnionFind.new('Some Person')}.to raise_exception(ArgumentError)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#find_root' do
|
23
|
+
union_find = UnionFind::UnionFind.new(people)
|
24
|
+
|
25
|
+
context 'when component does not exist' do
|
26
|
+
it 'raises an exception' do
|
27
|
+
expect {union_find.find_root('Some Person')}.to raise_exception(IndexError)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'when component exists' do
|
32
|
+
context 'when component has no parent' do
|
33
|
+
it 'returns same component' do
|
34
|
+
expect(union_find.find_root('Single')).to eq 'Single'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'when component has parent' do
|
39
|
+
create_family_tree(union_find)
|
40
|
+
|
41
|
+
it 'returns parent' do
|
42
|
+
expect(union_find.find_root('Daughter')).to eq 'Grandfather'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#union' do
|
49
|
+
context 'when one component gets connected to itself' do
|
50
|
+
union_find = UnionFind::UnionFind.new(people)
|
51
|
+
|
52
|
+
it 'returns the component' do
|
53
|
+
expect(union_find.union('Grandfather', 'Grandfather')).to be_nil
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'when one unconnected component gets connected to another unconnected component' do
|
58
|
+
union_find = UnionFind::UnionFind.new(people)
|
59
|
+
|
60
|
+
it 'returns the first component' do
|
61
|
+
expect(union_find.union('Grandfather', 'Father')).to eq 'Grandfather'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'when one unconnected component gets connected to a connected component' do
|
66
|
+
union_find = UnionFind::UnionFind.new(people)
|
67
|
+
create_family_tree(union_find)
|
68
|
+
|
69
|
+
it 'connects and returns the root of the larger tree' do
|
70
|
+
expect(union_find.union('Single', 'Father')).to eq 'Grandfather'
|
71
|
+
expect(union_find.connected?('Father', 'Single')).to be_truthy
|
72
|
+
expect(union_find.find_root('Father')).to eq 'Grandfather'
|
73
|
+
expect(union_find.find_root('Single')).to eq 'Grandfather'
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '#connected?' do
|
79
|
+
union_find = UnionFind::UnionFind.new(people)
|
80
|
+
create_family_tree(union_find)
|
81
|
+
|
82
|
+
context 'when two components are not connected' do
|
83
|
+
it 'returns false' do
|
84
|
+
expect(union_find.connected?('Father', 'Single')).to be_falsey
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'when two components are the same' do
|
89
|
+
it 'returns false' do
|
90
|
+
expect(union_find.connected?('Father', 'Father')).to be_truthy
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'when two components are connected' do
|
95
|
+
it 'returns false' do
|
96
|
+
expect(union_find.connected?('Grandfather', 'Daughter')).to be_truthy
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe '#count_isolated_components' do
|
102
|
+
context 'when no connections have been made' do
|
103
|
+
union_find = UnionFind::UnionFind.new(people)
|
104
|
+
|
105
|
+
it 'returns number of components' do
|
106
|
+
expect(union_find.count_isolated_components).to eq people.size
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'when connections have been made' do
|
111
|
+
union_find = UnionFind::UnionFind.new(people)
|
112
|
+
create_family_tree(union_find)
|
113
|
+
|
114
|
+
it 'returns number of components' do
|
115
|
+
expect(union_find.count_isolated_components).to eq 2
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
data/union_find.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'union_find/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "union_find"
|
8
|
+
spec.version = UnionFind::VERSION
|
9
|
+
spec.authors = ["Michael Imstepf"]
|
10
|
+
spec.email = ["michael.imstepf@gmail.com"]
|
11
|
+
spec.summary = %q{Weighted quick-union algorithm with path compression.}
|
12
|
+
spec.description = %q{Union Find is an algorithm that uses a disjoint-set data structure. It allows us to efficiently connect any items of a given list and to efficiently check whether two items of this list are connected (any degree of separation) or not.}
|
13
|
+
spec.homepage = "https://github.com/michaelimstepf/union-find"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
spec.add_development_dependency "pry"
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: union_find
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Michael Imstepf
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-06-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Union Find is an algorithm that uses a disjoint-set data structure. It
|
70
|
+
allows us to efficiently connect any items of a given list and to efficiently check
|
71
|
+
whether two items of this list are connected (any degree of separation) or not.
|
72
|
+
email:
|
73
|
+
- michael.imstepf@gmail.com
|
74
|
+
executables: []
|
75
|
+
extensions: []
|
76
|
+
extra_rdoc_files: []
|
77
|
+
files:
|
78
|
+
- ".gitignore"
|
79
|
+
- Gemfile
|
80
|
+
- LICENSE.txt
|
81
|
+
- README.md
|
82
|
+
- Rakefile
|
83
|
+
- lib/union_find.rb
|
84
|
+
- lib/union_find/version.rb
|
85
|
+
- spec/spec_helper.rb
|
86
|
+
- spec/union_find_spec.rb
|
87
|
+
- union_find.gemspec
|
88
|
+
homepage: https://github.com/michaelimstepf/union-find
|
89
|
+
licenses:
|
90
|
+
- MIT
|
91
|
+
metadata: {}
|
92
|
+
post_install_message:
|
93
|
+
rdoc_options: []
|
94
|
+
require_paths:
|
95
|
+
- lib
|
96
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0'
|
101
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
requirements: []
|
107
|
+
rubyforge_project:
|
108
|
+
rubygems_version: 2.2.2
|
109
|
+
signing_key:
|
110
|
+
specification_version: 4
|
111
|
+
summary: Weighted quick-union algorithm with path compression.
|
112
|
+
test_files:
|
113
|
+
- spec/spec_helper.rb
|
114
|
+
- spec/union_find_spec.rb
|