likes 0.2.1 → 0.2.2

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: 57b7324788939c732bf583a8396d012f9dbf35e0
4
- data.tar.gz: 5b1ec8d43c48ab7f9a3a3b62aeada4a8e330ee7d
3
+ metadata.gz: 58af381a556319bc76bbc45920a35ab2dcae39c9
4
+ data.tar.gz: 9b9abb9348acc601d2fe6439667502d9976f6d49
5
5
  SHA512:
6
- metadata.gz: 7260486cfbb33276b137441fc5a92f7ee7f380a52226ad3c7e504f323267dcfd01e51e6a22b148268f8893c39702b6d018a44999224ed7f87f21e574707fa9fa
7
- data.tar.gz: af76dc2ed91190930d7dc1370934b6fa9facb3b24957bc18b63de0490c0902e83983524bc7740382c8c6d5536276ebcdd8a5af453988041823d8a21473d6be83
6
+ metadata.gz: a5d316f21c3e6bfd5f2b0d539615d6e136bd05d92e729d051dcb9105b1280cce2831ebc0a55d22e184ea485a273dfd035d519cb6294ec6fbf6f422a09482f91f
7
+ data.tar.gz: 537f9e0c770cc4ef77c9864acb1e0c4650d39cbf51d9c96aa5fe82312a6992e7ce3711af51bbdefeb63cec37c9901837e2c47fdc4d3c6647a9dc8b112c90c70a
@@ -38,6 +38,7 @@ module Likes
38
38
  @liked = liked
39
39
  @items = liked.keys
40
40
  @people = likes_of.keys
41
+ @similarity_limit = INFINITY
41
42
  end
42
43
 
43
44
  # Solves the problem and returns recommendation list
@@ -53,7 +54,7 @@ module Likes
53
54
  private
54
55
 
55
56
  attr_reader :person, :likes_of, :liked, :items, :people,
56
- :signature, :hash_functions, :hashes
57
+ :signature, :hash_functions, :hashes, :similarity_limit
57
58
 
58
59
  def init_signature
59
60
  @signature = (0...MAX_HASH_FUNCTIONS_COUNT).map {
@@ -99,21 +100,41 @@ module Likes
99
100
  end
100
101
 
101
102
  def best_similarity
102
- similarities.values.max
103
+ @_best_similarity ||= similarities.
104
+ values.
105
+ select { |similarity| similarity < similarity_limit }.
106
+ max
103
107
  end
104
108
 
105
109
  def candidates
110
+ return [] unless best_similarity
106
111
  Hash[similarities.select { |_, similarity|
107
112
  best_similarity <= similarity * ALLOW_FLUCTUATION
108
113
  }].keys
109
114
  end
110
115
 
111
116
  def recommendations
117
+ return [] if candidates.empty?
118
+ non_empty_recommendations(recommendations_candidate)
119
+ end
120
+
121
+ def recommendations_candidate
112
122
  candidates.map { |other_person, _|
113
123
  likes_of.fetch(other_person) - own_likes
114
124
  }.flatten.uniq
115
125
  end
116
126
 
127
+ def non_empty_recommendations(solution)
128
+ return next_recommendations if solution.empty?
129
+ solution
130
+ end
131
+
132
+ def next_recommendations
133
+ @similarity_limit = best_similarity
134
+ @_best_similarity = nil
135
+ recommendations
136
+ end
137
+
117
138
  # Full complexity: D * O(likeset size * log N) ~ O(N log N) with big constant
118
139
  def compute_signature
119
140
  each_like do |_, _, row, column|
@@ -130,11 +151,16 @@ module Likes
130
151
 
131
152
  def each_column_of_likes(item, row, &blk)
132
153
  # only columns with 1 in matrix:
133
- liked.fetch(item).each_with_index do |person, column|
134
- blk[item, person, row, column]
154
+ liked.fetch(item).each do |person|
155
+ blk[item, person, row, person_column(person)]
135
156
  end
136
157
  end
137
158
 
159
+ def person_column(person)
160
+ @_person_column ||= {}
161
+ @_person_column[person] ||= people.index(person)
162
+ end
163
+
138
164
  # Complexity: D * O(1)
139
165
  def signature_step(row, column)
140
166
  signature.each_with_index do |signature_row, index|
@@ -1,3 +1,3 @@
1
1
  module Likes
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.2"
3
3
  end
@@ -19,8 +19,8 @@ module Likes
19
19
  context "when somebody literally likes everything" do
20
20
  let(:raw_likeset) { Fixtures.somebody_likes_literally_everything }
21
21
 
22
- it "possibly can choose this person as a candidate for recommendations" do
23
- expect(likeset.recommendations_for(1).sort).to eq([4, 9]).or eq([3, 4, 6, 7, 9, 17, 19])
22
+ it "does not choose this person as a candidate for recommendations" do
23
+ expect(likeset.recommendations_for(1).sort).to eq([4, 9])
24
24
  end
25
25
  end
26
26
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: likes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexey Fedorov