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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: 8a9f58e9e0fb04f0a297238643bc9ea12408a8b81e7ee3f962ecb34b30e4c410
4
- data.tar.gz: cdcd58cb09e29f012ded1af3a8dd1cb839343cc7c39f5810ec0b5d4c42c32ffa
2
+ SHA1:
3
+ metadata.gz: d9595ecd23f26afb21d717b31f2620c8d7b44b8a
4
+ data.tar.gz: 1d108a896a40f3401136c5e38c72bf2d5725488a
5
5
  SHA512:
6
- metadata.gz: 02c69ae62556ae04a058e5bc8d03e2db59cfb46e72b62717db46b1e7a2e44230f72e22dd05e8c4870dd1f946e71c0adf0605933bdcbe60f44bedc9ce58cdd2d8
7
- data.tar.gz: fac9c9fcc1c6da0ffc1d7d43f1cfe1d6bd2b25c28d61a38707c6eea3a03b5279b327443b47a7d3f462b1410e1f8ce9d4fa719d01c0d91d28379584f6496f586d
6
+ metadata.gz: 0c692328d3fa5f6dc0d8772a0ee0bbc1dd823a894a0ce62c48582aa2fbd6231969a415483e4e32a019b6855af069c715c4c02a2a4dff50ae8703bb53560b807e
7
+ data.tar.gz: 21cd8059926f31e911d7cae202d56a01820bfd2c17f303df5338ca6088f662e9778fc3d413f975940d85d4546639748a9dcb95f2c434ee2b434a9384998d106d
@@ -0,0 +1,11 @@
1
+ require_relative 'graph'
2
+
3
+ class DirectedGraph < Graph
4
+ def create_edge(origin_id, end_id)
5
+ @adjacency_list[origin_id].add(end_id)
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,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
@@ -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
@@ -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.0
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-12 00:00:00.000000000 Z
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 Priority Queue. More to come!
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.7.3
52
+ rubygems_version: 2.5.1
49
53
  signing_key:
50
54
  specification_version: 4
51
55
  summary: Ruby Data Structures