data_structures_101 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d0d92b27cd70fa2884b0dd6079a3a88581438604
4
- data.tar.gz: 174e6747d82bde23b1951693a9d4e66d7e677293
3
+ metadata.gz: f215d1362121ff577224993028a8870cd3fd1b82
4
+ data.tar.gz: 9785b4159ec72926f1fb81c5baeda8281d2840cb
5
5
  SHA512:
6
- metadata.gz: 34d2614a243cd65c97215ed7013b22db6b37b88f75203bbaeaf3ac4401bc109d9a92282f6bae1beda5114586fb6d8ee58cedecd537c9f04342cd1d3b35980c53
7
- data.tar.gz: bff1fb5af12eb3441061517b34a102213a273beb4ba727d54170413d0359d895ebdc8db17ff950e9326d00bf6f2f9760ec6cba98b2e5e965c039a6ea6ba9f67c
6
+ metadata.gz: 005a8f910dad00e6db443761b725eac89b384e1f6f79a0deb94d526c511d791b1b110d111159c80d202d142f3b0d2cb11aac984e925e468e25158fd3416f89e3
7
+ data.tar.gz: f477fe15da1f404dc753690b7d0ae27861f9785d81bcf6725ce2d8f862a8ad491075871e2883ac122d0a6f29edbe35ce35477975c1657afe39995b4df952b5b2
data/.travis.yml CHANGED
@@ -1,6 +1,14 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.4.0
5
- before_install: gem install bundler -v 1.14.6
4
+ - 2.4.0
6
5
  script: bundle exec rspec
6
+ deploy:
7
+ provider: rubygems
8
+ api_key:
9
+ secure: YDkCNjnzyBTEcZLjKqt6ep1rIHYGF6tbqwNVUXEOFiBpQA534xl8AcsNIcb4MZGcNzn9ZeJiHstIeHKKP135sLKnA00RptoVtNAHn9F5hBgDyPc5GyIEzml4wDv7NM+jcM4df39CEBIyYi+77vRUvUfrOJ+0RF7CxvlGX4ZUvbI+5edFXjt9ioVPOhG+V6FyTbGlNEG2Rj4lx6jjUF3HYVVhwHCva3F4uXNh/3CjZXvcJ6ZahKCiO0/pqxZsS6L/xfDaih/jg/8B3nQ2L7Lx+g5A8uNLCZ4u2G4SPoCg0a+mrttJAkIgTNC8reVBAbS9V7BV6/OJcJwwhJKNQ+UsleTv0oDdOWsSFgL8I2qtUJb7r1cpmFHi/LC5fnfpfC6xcoRk7sxrFboYsbm8yGt2KEk68Jregl9j0EqrHynog/9zFKx9Sfcrw2Fo+6oMACDYm3NzlcAo+6bQHni/kV94oaD58nZ3OQgvBMh4jeZ854jjCbpJaCMs2u2CgezjlTZCY7+E38t+/tiFlAOakVBSC9oGEYCFxh5X/clKXi7Q2PZj8j/pmcc51wmVFEMB5Led7kj1R1YWCnalhIZO4hpz83yBGCYZQgm2AZy0r8k741L9ab0H/KhMSJHGN2ym2Dgdpg1a0QdlMGVidIQGNjeSEx7TPkkDStuM588qKcR8C6M=
10
+ gem: data_structures_101
11
+ on:
12
+ tags: true
13
+ repo: renehernandez/data_structures_101
14
+ branch: master
data/_config.yml ADDED
@@ -0,0 +1 @@
1
+ theme: jekyll-theme-slate
@@ -1,5 +1,9 @@
1
1
  require "data_structures_101/version"
2
2
  require "data_structures_101/linked_list"
3
+ require "data_structures_101/hash/base_hash_table"
4
+ require "data_structures_101/hash/bucket"
5
+ require "data_structures_101/chained_hash_table"
6
+ require "data_structures_101/probe_hash_table"
3
7
 
4
8
  module DataStructures101
5
9
  # Your code goes here...
@@ -0,0 +1,40 @@
1
+ module DataStructures101
2
+
3
+ class ChainedHashTable < Hash::BaseHashTable
4
+
5
+ def initialize(capacity = 31, prime = 109345121, hash_lambda = nil)
6
+ super
7
+ end
8
+
9
+ private
10
+
11
+ def bucket_find(hash_code, key)
12
+ bucket = @table[hash_code]
13
+ return nil if bucket.nil?
14
+
15
+ bucket.find(key)
16
+ end
17
+
18
+ def bucket_insert(hash_code, key, value)
19
+ bucket = @table[hash_code]
20
+ bucket = @table[hash_code] = Hash::Bucket.new if bucket.nil?
21
+
22
+ old_size = bucket.size()
23
+ old_value = bucket.insert(key, value)
24
+ @size += (bucket.size - old_size)
25
+
26
+ old_value
27
+ end
28
+
29
+ def bucket_delete(hash_code, key)
30
+ bucket = @table[hash_code]
31
+ return nil if bucket.nil?
32
+
33
+ old_size = bucket.size
34
+ value = bucket.delete(key)
35
+ @size -= (old_size - bucket.size)
36
+
37
+ value
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,62 @@
1
+ module DataStructures101
2
+ module Hash
3
+ class BaseHashTable
4
+
5
+ attr_reader :size, :hash_lambda
6
+
7
+ def initialize(capacity, prime, hash_lambda = nil)
8
+ @capacity = capacity
9
+ @size = 0
10
+ @table = Array.new(@capacity)
11
+
12
+ random = Random.new
13
+ scale = random.rand(prime - 1) + 1
14
+ shift = random.rand(prime)
15
+
16
+ @hash_lambda = if hash_lambda.nil?
17
+ ->(key) { return (((key.hash * scale + shift) % prime) % @capacity).abs }
18
+ else
19
+ hash_lambda
20
+ end
21
+ end
22
+
23
+ def []=(key, value)
24
+ insert(key, value)
25
+ end
26
+
27
+ def insert(key, value)
28
+ old_value = bucket_insert(hash_lambda.call(key), key, value)
29
+
30
+ # keep load factor <= 0.5
31
+ resize(new_capacity) if @size > @capacity / 2
32
+
33
+ old_value
34
+ end
35
+
36
+ def [](key)
37
+ bucket_find(hash_lambda.call(key), key)
38
+ end
39
+
40
+ def delete(key)
41
+ bucket_delete(hash_lambda.call(key), key)
42
+ end
43
+
44
+ private
45
+
46
+ def new_capacity()
47
+ 2 * capacity - 1
48
+ end
49
+
50
+ def resize(new_capacity)
51
+ @capacity = new_capacity
52
+
53
+ buffer = self.map { |key, value| [key, value] }
54
+
55
+ create_table
56
+ @size = 0
57
+
58
+ buffer.each { |key, value| self[key] = value }
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,52 @@
1
+ module DataStructures101
2
+ module Hash
3
+ class Bucket
4
+
5
+ attr_reader :table
6
+
7
+ def initialize()
8
+ @table = []
9
+ end
10
+
11
+ def [](key)
12
+ find(key)
13
+ end
14
+
15
+ def []=(key, value)
16
+ insert(key, value)
17
+ end
18
+
19
+ def insert(key, value)
20
+ idx = @table.find_index {|_key, _| _key == key}
21
+
22
+ if idx.nil?
23
+ @table << [key, value]
24
+ return nil
25
+ else
26
+ value, @table[idx][1] = @table[idx][1], value
27
+ return value
28
+ end
29
+ end
30
+
31
+ def size()
32
+ @table.size
33
+ end
34
+
35
+ def find(key)
36
+ pair = @table.find {|_key, _| _key == key}
37
+ pair.nil? ? nil : pair.last
38
+ end
39
+
40
+ def delete(key)
41
+ idx = @table.find_index {|_key, _| _key == key}
42
+ return nil if idx.nil?
43
+
44
+ value = @table[idx].last
45
+ @table[idx] = @table.last if idx != @table.size - 1
46
+ @table.pop
47
+ value
48
+ end
49
+
50
+ end
51
+ end
52
+ end
@@ -69,36 +69,20 @@ module DataStructures101
69
69
  self
70
70
  end
71
71
 
72
- def first(*args)
73
- if args.size == 0
74
- return @head.next.value
75
- end
72
+ def first(n = nil)
73
+ return @head.next.value if n.nil?
76
74
 
77
- if args.size > 1
78
- raise ArgumentError, "wrong number of arguments (given #{args.size}, expected 1)"
79
- end
75
+ raise ArgumentError, "negative array size" if n < 0
80
76
 
81
- if args.first < 0
82
- raise ArgumentError, "negative array size"
83
- end
84
-
85
- return new_list_from_range(0, args.first - 1)
77
+ return new_list_from_range(0, n - 1)
86
78
  end
87
79
 
88
- def last(*args)
89
- if args.size == 0
90
- return @tail.prev.value
91
- end
92
-
93
- if args.size > 1
94
- raise ArgumentError, "wrong number of arguments (given #{args.size}, expected 1)"
95
- end
96
-
97
- if args.first < 0
98
- raise ArgumentError, "negative array size"
99
- end
80
+ def last(n = nil)
81
+ return @tail.prev.value if n.nil?
82
+
83
+ raise ArgumentError, "negative array size" if n < 0
100
84
 
101
- return new_list_from_range(size - args.first, size - 1)
85
+ return new_list_from_range(size - n, size - 1)
102
86
  end
103
87
 
104
88
  def push(*values)
@@ -0,0 +1,79 @@
1
+ require 'singleton'
2
+
3
+ module DataStructures101
4
+ class ProbeHashTable < Hash::BaseHashTable
5
+
6
+ attr_reader :probe_lambda
7
+
8
+ def initialize(capacity = 31, prime = 109345121,
9
+ hash_lambda = nil, probe_lambda = nil)
10
+ super(capacity, prime, hash_lambda)
11
+
12
+ @probe_lambda = if probe_lambda.nil?
13
+ ->(h, i) { return (h + i) % @capacity }
14
+ else
15
+ probe_lambda
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ Sentinel = Class.new do
22
+ include Singleton
23
+ end
24
+
25
+ def bucket_find(hash_code, key)
26
+ idx = find_slot(hash_code, key)
27
+
28
+ slot_available?(idx) ? nil : @table[idx].last
29
+ end
30
+
31
+ def bucket_insert(hash_code, key, value)
32
+ idx = find_slot(hash_code, key)
33
+
34
+ if !slot_available?(idx)
35
+ old_value = @table[idx].last
36
+ @table[idx] = [key, value]
37
+ return old_value
38
+ end
39
+
40
+ @table[idx] = [key, value]
41
+ @size += 1
42
+
43
+ nil
44
+ end
45
+
46
+ def bucket_delete(hash_code, key)
47
+ idx = find_slot(hash_code, key)
48
+ return nil if slot_available?(idx)
49
+
50
+ value = @table[idx].last
51
+ @table[idx] = Sentinel.instance
52
+ @size -= 1
53
+
54
+ value
55
+ end
56
+
57
+ def find_slot(h, key)
58
+ idx = -1
59
+
60
+ j = 0
61
+ loop do
62
+ i = @probe_lambda.call(h, j)
63
+ if slot_available?(i)
64
+ idx = i if idx == -1
65
+ break if @table[i].nil?
66
+ elsif @table[i].first == key
67
+ return i
68
+ end
69
+ j += 1
70
+ end
71
+
72
+ idx
73
+ end
74
+
75
+ def slot_available?(i)
76
+ @table[i].nil? || @table[i] == Sentinel.instance
77
+ end
78
+ end
79
+ end
@@ -1,3 +1,3 @@
1
1
  module DataStructures101
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: data_structures_101
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - aegis
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-03-11 00:00:00.000000000 Z
11
+ date: 2017-08-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,11 +66,16 @@ files:
66
66
  - LICENSE.txt
67
67
  - README.md
68
68
  - Rakefile
69
+ - _config.yml
69
70
  - bin/console
70
71
  - bin/setup
71
72
  - data_structures_101.gemspec
72
73
  - lib/data_structures_101.rb
74
+ - lib/data_structures_101/chained_hash_table.rb
75
+ - lib/data_structures_101/hash/base_hash_table.rb
76
+ - lib/data_structures_101/hash/bucket.rb
73
77
  - lib/data_structures_101/linked_list.rb
78
+ - lib/data_structures_101/probe_hash_table.rb
74
79
  - lib/data_structures_101/version.rb
75
80
  homepage: https://github.com/renehernandez/bok-data_structures_101
76
81
  licenses:
@@ -92,7 +97,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
92
97
  version: '0'
93
98
  requirements: []
94
99
  rubyforge_project:
95
- rubygems_version: 2.6.8
100
+ rubygems_version: 2.6.11
96
101
  signing_key:
97
102
  specification_version: 4
98
103
  summary: DataStructures101 is a simple gem that groups several implementations of