ruby_structures 2.4.0 → 2.5.0
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 +5 -5
- data/lib/data_structures/directed_graph.rb +11 -0
- data/lib/data_structures/graph.rb +98 -0
- data/lib/data_structures/heap.rb +10 -0
- data/lib/data_structures/weighted_directed_graph.rb +11 -0
- data/lib/data_structures/weighted_graph.rb +71 -0
- data/lib/ruby_structures.rb +4 -0
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d9595ecd23f26afb21d717b31f2620c8d7b44b8a
|
4
|
+
data.tar.gz: 1d108a896a40f3401136c5e38c72bf2d5725488a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0c692328d3fa5f6dc0d8772a0ee0bbc1dd823a894a0ce62c48582aa2fbd6231969a415483e4e32a019b6855af069c715c4c02a2a4dff50ae8703bb53560b807e
|
7
|
+
data.tar.gz: 21cd8059926f31e911d7cae202d56a01820bfd2c17f303df5338ca6088f662e9778fc3d413f975940d85d4546639748a9dcb95f2c434ee2b434a9384998d106d
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
class Graph
|
4
|
+
def initialize
|
5
|
+
@adjacency_list = Hash.new { |h, k| h[k] = Set.new }
|
6
|
+
end
|
7
|
+
|
8
|
+
def [](id)
|
9
|
+
@adjacency_list[id]
|
10
|
+
end
|
11
|
+
|
12
|
+
def add_vertex(id)
|
13
|
+
raise RuntimeError.new("#{id} is already a Vertex") if @adjacency_list.include?(id)
|
14
|
+
@adjacency_list[id]
|
15
|
+
end
|
16
|
+
|
17
|
+
def delete_vertex(id)
|
18
|
+
raise RuntimeError.new("#{id} is not a Vertex") unless @adjacency_list.include?(id)
|
19
|
+
@adjacency_list.delete(id)
|
20
|
+
end
|
21
|
+
|
22
|
+
def create_edge(id1, id2)
|
23
|
+
raise RuntimeError.new("#{id1} is not a Vertex") unless @adjacency_list.include?(id1)
|
24
|
+
raise RuntimeError.new("#{id2} is not a Vertex") unless @adjacency_list.include?(id2)
|
25
|
+
@adjacency_list[id1].add(id2)
|
26
|
+
@adjacency_list[id2].add(id1)
|
27
|
+
end
|
28
|
+
|
29
|
+
def delete_edge(id1, id2)
|
30
|
+
raise RuntimeError.new("#{id1} is not a Vertex") unless @adjacency_list.include?(id1)
|
31
|
+
raise RuntimeError.new("#{id1} is not connected to #{id2}") unless @adjacency_list[id1].include?(id2)
|
32
|
+
@adjacency_list[id1].delete(id2)
|
33
|
+
@adjacency_list[id2].delete(id1)
|
34
|
+
end
|
35
|
+
|
36
|
+
def adjacent?(id1, id2)
|
37
|
+
raise RuntimeError.new("#{id1} is not a Vertex") unless @adjacency_list.include?(id1)
|
38
|
+
raise RuntimeError.new("#{id2} is not a Vertex") unless @adjacency_list.include?(id2)
|
39
|
+
@adjacency_list[id1].include?(id2)
|
40
|
+
end
|
41
|
+
|
42
|
+
def adjacent_vertices(id)
|
43
|
+
raise RuntimeError.new("#{id} is not a Vertex") unless @adjacency_list.include?(id)
|
44
|
+
@adjacency_list[id]
|
45
|
+
end
|
46
|
+
|
47
|
+
def depth_first_search(target_id=nil, start_id=nil, &prc)
|
48
|
+
raise ArgumentError.new('Must pass either a target value or a block') unless (target_id || prc) && !(target_id && prc)
|
49
|
+
prc ||= Proc.new { |vertex| vertex == target_id }
|
50
|
+
|
51
|
+
return false if @adjacency_list.empty?
|
52
|
+
current_vertex = start_id || @adjacency_list.first.first
|
53
|
+
@memo = Set.new unless start_id
|
54
|
+
@memo ||= Set.new
|
55
|
+
|
56
|
+
unless @memo.include?(current_vertex)
|
57
|
+
return true if prc.call(current_vertex)
|
58
|
+
@memo.add(current_vertex)
|
59
|
+
end
|
60
|
+
|
61
|
+
current_adjacency_list = @adjacency_list[current_vertex]
|
62
|
+
current_adjacency_list.each do |vertex|
|
63
|
+
if @memo.include?(vertex)
|
64
|
+
next
|
65
|
+
else
|
66
|
+
@memo.add(vertex)
|
67
|
+
end
|
68
|
+
|
69
|
+
return true if prc.call(vertex)
|
70
|
+
result = depth_first_search(nil, vertex, &prc)
|
71
|
+
return result if result
|
72
|
+
end
|
73
|
+
|
74
|
+
false
|
75
|
+
end
|
76
|
+
|
77
|
+
def breadth_first_search(target_id=nil, start_id=nil, &prc)
|
78
|
+
raise ArgumentError.new('Must pass either a target value or a block') unless (target_id || prc) && !(target_id && prc)
|
79
|
+
prc ||= Proc.new { |vertex| vertex == target_id }
|
80
|
+
|
81
|
+
return false if @adjacency_list.empty?
|
82
|
+
start_id ||= @adjacency_list.first.first
|
83
|
+
vertex_queue = [start_id]
|
84
|
+
|
85
|
+
memo = Set.new
|
86
|
+
until vertex_queue.empty?
|
87
|
+
current_vertex = vertex_queue.shift
|
88
|
+
return true if prc.call(current_vertex)
|
89
|
+
|
90
|
+
current_adjacency_list = @adjacency_list[current_vertex]
|
91
|
+
|
92
|
+
vertex_queue += current_adjacency_list.to_a.reject { |vertex| memo.include?(vertex) }
|
93
|
+
memo.add(current_vertex)
|
94
|
+
end
|
95
|
+
|
96
|
+
false
|
97
|
+
end
|
98
|
+
end
|
data/lib/data_structures/heap.rb
CHANGED
@@ -15,6 +15,16 @@ class Heap
|
|
15
15
|
@store = []
|
16
16
|
end
|
17
17
|
|
18
|
+
def to_a
|
19
|
+
arr = []
|
20
|
+
copy = self.dup
|
21
|
+
copy.instance_variable_set(:@store, @store.dup)
|
22
|
+
until copy.empty?
|
23
|
+
arr << copy.extract
|
24
|
+
end
|
25
|
+
arr
|
26
|
+
end
|
27
|
+
|
18
28
|
def to_s
|
19
29
|
"Heap: head=#{self.peek || 'nil'}, length=#{self.length}"
|
20
30
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require_relative 'weighted_graph'
|
2
|
+
|
3
|
+
class WeightedDirectedGraph < WeightedGraph
|
4
|
+
def create_edge(origin_id, end_id, weight)
|
5
|
+
@adjacency_list[origin_id][end_id] = weight
|
6
|
+
end
|
7
|
+
|
8
|
+
def delete_edge(origin_id, end_id)
|
9
|
+
@adjacency_list[origin_id].delete(end_id)
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
class WeightedGraph
|
2
|
+
def initialize
|
3
|
+
@adjacency_list = Hash.new { |h, k| h[k] = {} }
|
4
|
+
end
|
5
|
+
|
6
|
+
def [](id)
|
7
|
+
@adjacency_list[id]
|
8
|
+
end
|
9
|
+
|
10
|
+
def add_vertex(id)
|
11
|
+
@adjacency_list[id]
|
12
|
+
end
|
13
|
+
|
14
|
+
def delete_vertex(id)
|
15
|
+
@adjacency_list.delete(id)
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_edge(id1, id2, weight)
|
19
|
+
@adjacency_list[id1][id2] = weight
|
20
|
+
@adjacency_list[id2][id1] = weight
|
21
|
+
end
|
22
|
+
|
23
|
+
def delete_edge(id1, id2)
|
24
|
+
@adjacency_list[id1].delete(id2)
|
25
|
+
@adjacency_list[id2].delete(id1)
|
26
|
+
end
|
27
|
+
|
28
|
+
def adjacent?(id1, id2)
|
29
|
+
raise RuntimeError.new("#{id1} is not a Vertex") unless @adjacency_list.include?(id1)
|
30
|
+
raise RuntimeError.new("#{id2} is not a Vertex") unless @adjacency_list.include?(id2)
|
31
|
+
@adjacency_list[id1].include?(id2)
|
32
|
+
end
|
33
|
+
|
34
|
+
def adjacent_vertices(id)
|
35
|
+
raise RuntimeError.new("#{id} is not a Vertex") unless @adjacency_list.include?(id)
|
36
|
+
@adjacency_list[id]
|
37
|
+
end
|
38
|
+
|
39
|
+
def highest_weight_adjacent(id)
|
40
|
+
adjacent_vertices = self.adjacent_vertices(id)
|
41
|
+
return nil if adjacent_vertices.empty?
|
42
|
+
|
43
|
+
highest = nil
|
44
|
+
highest_weight = nil
|
45
|
+
adjacent_vertices.each do |vertex, weight|
|
46
|
+
if highest_weight == nil || weight > highest_weight
|
47
|
+
highest = vertex
|
48
|
+
highest_weight = weight
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
highest
|
53
|
+
end
|
54
|
+
|
55
|
+
def lowest_weight_adjacent(id)
|
56
|
+
adjacent_vertices = self.adjacent_vertices(id)
|
57
|
+
return nil if adjacent_vertices.empty?
|
58
|
+
|
59
|
+
lowest = nil
|
60
|
+
lowest_weight = nil
|
61
|
+
adjacent_vertices.each do |vertex, weight|
|
62
|
+
if lowest_weight == nil || weight < lowest_weight
|
63
|
+
lowest = vertex
|
64
|
+
lowest_weight = weight
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
lowest
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
data/lib/ruby_structures.rb
CHANGED
@@ -5,3 +5,7 @@ require 'data_structures/binary_tree'
|
|
5
5
|
require 'data_structures/lru_cache'
|
6
6
|
require 'data_structures/heap'
|
7
7
|
require 'data_structures/priority_queue'
|
8
|
+
require 'data_structures/graph'
|
9
|
+
require 'data_structures/directed_graph'
|
10
|
+
require 'data_structures/weighted_graph'
|
11
|
+
require 'data_structures/weighted_directed_graph'
|
metadata
CHANGED
@@ -1,29 +1,33 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby_structures
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason Numeroff
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-05-
|
11
|
+
date: 2018-05-17 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Ruby implementations of a Stack, Queue, Linked List, Binary Tree, LRU
|
14
|
-
Cache, Heap and
|
14
|
+
Cache, Heap, Priority Queue, Graph and Weighted Graph. More to come!
|
15
15
|
email: jnumeroff@hotmail.com
|
16
16
|
executables: []
|
17
17
|
extensions: []
|
18
18
|
extra_rdoc_files: []
|
19
19
|
files:
|
20
20
|
- lib/data_structures/binary_tree.rb
|
21
|
+
- lib/data_structures/directed_graph.rb
|
22
|
+
- lib/data_structures/graph.rb
|
21
23
|
- lib/data_structures/heap.rb
|
22
24
|
- lib/data_structures/linked_list.rb
|
23
25
|
- lib/data_structures/lru_cache.rb
|
24
26
|
- lib/data_structures/priority_queue.rb
|
25
27
|
- lib/data_structures/queue.rb
|
26
28
|
- lib/data_structures/stack.rb
|
29
|
+
- lib/data_structures/weighted_directed_graph.rb
|
30
|
+
- lib/data_structures/weighted_graph.rb
|
27
31
|
- lib/ruby_structures.rb
|
28
32
|
homepage: https://github.com/Numie/RubyStructures
|
29
33
|
licenses:
|
@@ -45,7 +49,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
45
49
|
version: '0'
|
46
50
|
requirements: []
|
47
51
|
rubyforge_project:
|
48
|
-
rubygems_version: 2.
|
52
|
+
rubygems_version: 2.5.1
|
49
53
|
signing_key:
|
50
54
|
specification_version: 4
|
51
55
|
summary: Ruby Data Structures
|