ruby_structures 2.4.0 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
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