data_structures_101 0.1.0 → 0.2.1

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
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