closest_neighbours 0.2.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
  SHA256:
3
- metadata.gz: 1dc9ec134c754981b57d69366f513ec4768678472b18d5cf79c61513bd625b12
4
- data.tar.gz: 27c1a7596b2708fab789d7e695d39455d104b7de76f00e0271bd6c3a4d3dec46
3
+ metadata.gz: 576f497b27d6ebba11b54ebb51a3ec247930037fbe149ed0e2ae92bb8b073c92
4
+ data.tar.gz: b4d3540e6218de82d923eeb688819d13ece9610967bfc09bdad62dcf08804cb3
5
5
  SHA512:
6
- metadata.gz: c01f230fb3bc47584b249804c216d55bb16a2cff8dceecb187dd6a82d0bb7d860a6032a08c278f0a5ecaf1910100a36c3e7df5a3dc849d0bd2a34a29b5fd1b7b
7
- data.tar.gz: 2bf2f4574fc4b2f0db9fbd36a7485bc790418b3e9b67c87570f827694ce5e0ab5fb9cf87343c663b6ddc8866abaf13fea9e16b6768c501531e368e63c2f54fef
6
+ metadata.gz: ea2d077995597448fa9430e97c07f1f5a127a1fdc5f33cf6b08152cffa307ecde35cdf044ef0f111de07a3f0562cd8d12aa2cd7d30cd16c87ec44e1eb704e5de
7
+ data.tar.gz: bd1c0aff794d5aedcfeaa2be93970f3574e227d46e58ea0eb7fac632da15c3d11324c169724c51d0178637d08e88b9a117492404021b0bd917802a049fa50b29
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- closest_neighbours (0.2.0)
4
+ closest_neighbours (0.2.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'closest_neighbours/indexer'
4
+
3
5
  module ClosestNeighbours
4
6
  # Split an Enumerable into specified number of groups containing the closest elements in each group.
5
7
  class Grouper
@@ -8,76 +10,52 @@ module ClosestNeighbours
8
10
  end
9
11
 
10
12
  def call(groups = 1, data = [])
11
- @groups = groups
12
- @data = data
13
-
14
- validate!
15
-
16
- if groups >= size
17
- wraped_data + blanks
18
- else
19
- ranges.map { |range| ordered_data[range] }
20
- end
21
- end
22
-
23
- private
24
-
25
- attr_reader :groups, :data, :orderer
26
-
27
- def validate!
28
13
  raise NonIntegerGroupsError unless groups.is_a? Integer
29
14
  raise NonEnumberableArgumentError unless data.is_a? Enumerable
30
15
  raise InsufficientGroupsError if groups < 1
31
- raise IncomparableElementError unless comparable_elements?
32
- end
16
+ raise IncomparableElementError unless data.all? { |e| e <=> data.first }
33
17
 
34
- def size
35
- data.count
18
+ GrouperHelper.new(groups, orderer.call(data)).call
36
19
  end
37
20
 
38
- def blanks
39
- Array.new(number_of_blanks, [])
40
- end
21
+ private
41
22
 
42
- def number_of_blanks
43
- [0, groups - size].max
44
- end
23
+ attr_reader :orderer
45
24
 
46
- def wraped_data
47
- ordered_data.map { |x| [x] }
48
- end
25
+ # Helper class to index data and extract ranges from an enumberble
26
+ class GrouperHelper
27
+ def initialize(groups, data)
28
+ @groups = groups
29
+ @data = data
30
+ end
49
31
 
50
- def ranges
51
- [0..indexes[0]] +
52
- (indexes << size).each_cons(2)
53
- .map { |(left, right)| (left + 1)..right }
54
- end
32
+ def call
33
+ if groups == 1
34
+ [data]
35
+ elsif groups >= data.count
36
+ cells + blanks
37
+ else
38
+ ranges.map { |range| data[range] }
39
+ end
40
+ end
55
41
 
56
- def indexes
57
- @indexes ||= differences_with_indices
58
- .lazy
59
- .map(&:last)
60
- .first(groups - 1)
61
- .sort
62
- end
42
+ private
63
43
 
64
- def differences_between_each_pair
65
- ordered_data.each_cons(2).map { |(a, b)| b - a }
66
- end
44
+ attr_reader :groups, :data
67
45
 
68
- def differences_with_indices
69
- differences_between_each_pair
70
- .map.with_index { |x, i| [x, i] }
71
- .sort
72
- .reverse
73
- end
46
+ def cells
47
+ data.map { |x| [x] }
48
+ end
74
49
 
75
- def ordered_data
76
- @ordered_data ||= orderer.call(data)
77
- end
50
+ def blanks
51
+ Array.new([0, groups - data.count].max, [])
52
+ end
78
53
 
79
- def comparable_elements?
80
- data.all? { |e| data.first <=> e }
54
+ def ranges
55
+ Indexer.new(groups, data).call
56
+ .each_cons(2)
57
+ .map { |(left, right)| left...right }
58
+ end
81
59
  end
82
60
  end
83
61
  end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ClosestNeighbours
4
+ # Determines the indexes where the data need to be grouped
5
+ class Indexer
6
+ def initialize(groups = 1, data = [])
7
+ @groups = groups
8
+ @data = data
9
+ end
10
+
11
+ def call
12
+ [0] + indexes + [data.count]
13
+ end
14
+
15
+ private
16
+
17
+ attr_reader :groups, :data
18
+
19
+ def indexes
20
+ if same?
21
+ even
22
+ else
23
+ dynamic
24
+ end
25
+ end
26
+
27
+ def same?
28
+ differences_between_each_element.all? { |x| x == differences_between_each_element.first }
29
+ end
30
+
31
+ def even
32
+ (1...groups).map do |i|
33
+ i * (data.count / groups.to_f).ceil
34
+ end
35
+ end
36
+
37
+ def dynamic
38
+ differences_between_each_element
39
+ .with_index
40
+ .sort_by { |(diff, _)| -diff }
41
+ .first(groups - 1)
42
+ .map { |(_, i)| i + 1 }
43
+ .sort
44
+ end
45
+
46
+ def differences_between_each_element
47
+ data.lazy
48
+ .each_cons(2)
49
+ .map { |(lower, higher)| higher - lower }
50
+ end
51
+ end
52
+ end
@@ -1,3 +1,3 @@
1
1
  module ClosestNeighbours
2
- VERSION = '0.2.0'.freeze
2
+ VERSION = '0.2.1'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: closest_neighbours
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Milanese
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-09-17 00:00:00.000000000 Z
11
+ date: 2021-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -137,6 +137,7 @@ files:
137
137
  - lib/closest_neighbours/errors/non_enumberable_argument_error.rb
138
138
  - lib/closest_neighbours/errors/non_integer_groups_error.rb
139
139
  - lib/closest_neighbours/grouper.rb
140
+ - lib/closest_neighbours/indexer.rb
140
141
  - lib/closest_neighbours/orderers/default_order.rb
141
142
  - lib/closest_neighbours/orderers/sorted_order.rb
142
143
  - lib/closest_neighbours/version.rb
@@ -146,7 +147,7 @@ licenses:
146
147
  metadata:
147
148
  homepage_uri: https://github.com/aussidavid/closest_neighbours
148
149
  source_code_uri: https://github.com/aussidavid/closest_neighbours
149
- post_install_message:
150
+ post_install_message:
150
151
  rdoc_options: []
151
152
  require_paths:
152
153
  - lib
@@ -162,7 +163,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
162
163
  version: '0'
163
164
  requirements: []
164
165
  rubygems_version: 3.1.6
165
- signing_key:
166
+ signing_key:
166
167
  specification_version: 4
167
168
  summary: Takes an array of elements, groups them by their ordered closest neighbors
168
169
  into n groups