pcbr 0.2.0 → 0.3.0

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.
Files changed (6) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -1
  3. data/lib/pcbr.rb +56 -34
  4. data/pcbr.gemspec +3 -1
  5. data/spec/_spec.rb +38 -6
  6. metadata +20 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2871f614f5c3e9fdf49297ebca1fc97e148eb3e3
4
- data.tar.gz: 162ccfbbcaebf10c1e3a762f68ffcbc0b326888d
3
+ metadata.gz: 2ce39501eee28e4881d896c138a0049899912b8a
4
+ data.tar.gz: 68060e95d3921de4b105fd48227fc776d93ff744
5
5
  SHA512:
6
- metadata.gz: 2f24b3e3e90bbde660ecd8c810e17f31cc949eefdb12b9d2b4a88746b9916023f16b6e379bc4f9fe9e7206b6741cdc4d489b07b6d768bb2ad7303973004867c7
7
- data.tar.gz: 1702bac320df836e08bb1fef10195fa00b97ccd01a15b795cd8e082f6005c1c8f04233c9891eab78e4b392937fce1c4c73542de90e5f5812b9b4650899080d60
6
+ metadata.gz: b7c3edd47fd4012722dffd750833187b5951943543aca19b3b507409f787f5ec60ea1e08adb337967770a9d4494ec8e0cc7d18337a0ae68230f0b42f226101be
7
+ data.tar.gz: 93051d2392065a23d4cb2918c79771e11cb08a1c6df7a13489f6bc58fe2284beb5410b850eec86251f94eed3f28e015664c3bf9d93ea1e073965fcafd160003a
data/README.md CHANGED
@@ -12,7 +12,9 @@ The first idea of rating items by one-to-one comparison was about QuakeLive play
12
12
 
13
13
  TODO: describe/illustrate algorithm?
14
14
 
15
- At the moment it's a "proof of concept" -- it needs huge optimisations for lookups, maybe using trees.
15
+ ~~At the moment it's a "proof of concept" -- it needs huge optimisations for lookups, maybe using trees.~~
16
+
17
+ It worked fine in production for a project with huge computations where you can't find the best solution but have to find anything good in adequate time. Traversing the tree using this with a vector of `[leaf's quality, depth]` made things better than depth-first search with lots of ueristics.
16
18
 
17
19
  ### Installation
18
20
 
@@ -1,47 +1,69 @@
1
- class PCBR
1
+ require "deep_dup"
2
2
 
3
- VERSION = "0.2.0"
3
+ module PCBR
4
+ VERSION = "0.3.0"
4
5
 
5
- attr_reader :table
6
+ class Error < RuntimeError
7
+ # def initialize body
8
+ # super "#{Module.nesting[1]} error: #{body}"
9
+ # end
10
+ end
6
11
 
7
- ARRAY_101 = [0, 0, 0]
8
- def initialize &block
9
- @table = []
10
- @callback = block || ( lambda do |a_, b_|
11
- array = ARRAY_101.dup
12
- [*a_].zip([*b_]) do |a, b|
13
- next unless t = a <=> b
14
- array[t] = t
15
- end
16
- array.inject :+
17
- end )
12
+ def self.new &block
13
+ Storage.new &block
18
14
  end
19
15
 
20
- # def size
21
- # @table.size
22
- # end
16
+ ARRAY_101 = [0, 0, 0]
17
+ class Storage
18
+ attr_reader :table
23
19
 
24
- def store key, *vector
25
- vector = vector.empty? ? key : vector.first
26
- score = 0
27
- @table.each do |item|
28
- fail unless [*vector].size == [*item[1]].size
20
+ def initialize &block
21
+ @table = []
22
+ @callback = block || lambda{ |a_, b_|
23
+ ARRAY_101.dup.tap do |array|
24
+ [*a_].zip([*b_]) do |a, b|
25
+ t = a <=> b and array[t] = t
26
+ end
27
+ end.inject :+
28
+ }
29
+ end
29
30
 
30
- point = @callback.call vector, item[1]
31
+ def store key, vector = nil
32
+ raise Error.new "duplicating key" if @table.assoc key
33
+ key = DeepDup.deep_dup key
34
+ vector = if vector
35
+ DeepDup.deep_dup vector
36
+ else
37
+ Array key
38
+ end
39
+ score = 0
40
+ @table.each do |item|
41
+ # TODO test of this exception
42
+ raise Error.new "comparison vectors are of the different length" unless vector.size == item[1].size
43
+ point = @callback.call vector, item[1]
44
+ score += point
45
+ item[2] -= point
46
+ end
47
+ @table.push [key, vector, score]
48
+ end
31
49
 
32
- score += point
33
- item[2] -= point
50
+ def score key
51
+ @table.assoc(key)[2]
34
52
  end
35
- @table.push [key, vector, score]
36
- end
37
53
 
38
- def score key
39
- @table.assoc(key)[2]
40
- end
54
+ def sorted
55
+ # from the best to the worst
56
+ @table.sort_by.with_index{ |item, i| [-item[2], i] }.map(&:first)
57
+ end
41
58
 
42
- def sorted
43
- # from the best to the worst
44
- @table.sort_by.with_index{ |item, i| [-item[2], i] }.map(&:first)
45
- end
59
+ # def quality
60
+ # factorial = ->x{ (1..x).inject(:*) }
61
+ # (2...@table.size).each do |sublength|
62
+ # combinations = factorial[@table.size] / factorial[sublength] / factorial[@table.size - sublength]
63
+ # comparisons = sublength * (sublength - 1) / 2
64
+ # p [sublength, combinations, comparisons, combinations * comparisons]
65
+ # end
66
+ # end
46
67
 
68
+ end
47
69
  end
@@ -11,7 +11,9 @@ Gem::Specification.new do |spec|
11
11
  spec.files = `git ls-files -z`.split("\x0")
12
12
  spec.test_files = ["spec/"]
13
13
 
14
- spec.add_development_dependency "bundler", "~> 1.12.0"
14
+ spec.add_dependency "deep_dup"
15
+
16
+ spec.add_development_dependency "bundler"
15
17
  spec.add_development_dependency "rspec", "~> 3.3.0"
16
18
 
17
19
  spec.required_ruby_version = ">= 2.0.0"
@@ -13,12 +13,12 @@ describe "basic specs" do
13
13
  expect(rating.sorted).to eq([2, 1])
14
14
  end
15
15
 
16
- example "#size", skip: :deprecated do
17
- rating = PCBR.new
18
- rating.store 1
19
- rating.store 2
20
- expect(rating.size).to eq(2)
21
- end
16
+ # example "#size" do
17
+ # rating = PCBR.new
18
+ # rating.store 1
19
+ # rating.store 2
20
+ # expect(rating.size).to eq(2)
21
+ # end
22
22
 
23
23
  example "Nil elements in vector are ignored" do
24
24
  rating = PCBR.new
@@ -63,6 +63,38 @@ describe "basic specs" do
63
63
  expect(rating.table).to eq(table)
64
64
  end
65
65
 
66
+ # example "quality estimation" do
67
+ # rating = PCBR.new
68
+ # table = [
69
+ # [1, [1, 1]],
70
+ # [2, [2, 2]],
71
+ # [3, [0, 0]],
72
+ # [4, [1, 2]],
73
+ # [6, [1, 1]],
74
+ # [5, [0, 2]],
75
+ # ].each do |key, vector, |
76
+ # rating.store key, vector
77
+ # end
78
+ # end
79
+
80
+ example "duplicating keys are forbidden" do
81
+ rating = PCBR.new
82
+ rating.store 0
83
+ expect{ rating.store 0 }.to raise_error PCBR::Error
84
+ end
85
+
86
+ example "keys and vectors are dupped" do
87
+ rating = PCBR.new
88
+ a = [[1]]
89
+ v = [0]
90
+ rating.store a, v
91
+ a[0][0] = 2
92
+ rating.store [[2]], [1] # expect no PCBR::Error
93
+ v[0] = 3
94
+ rating.store [[3]], [2]
95
+ expect(rating.sorted).to eq [[[3]], [[2]], [[1]]]
96
+ end
97
+
66
98
  end
67
99
 
68
100
 
metadata CHANGED
@@ -1,29 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pcbr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Maslov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-07 00:00:00.000000000 Z
11
+ date: 2017-12-06 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: deep_dup
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
- - - ~>
31
+ - - '>='
18
32
  - !ruby/object:Gem::Version
19
- version: 1.12.0
33
+ version: '0'
20
34
  type: :development
21
35
  prerelease: false
22
36
  version_requirements: !ruby/object:Gem::Requirement
23
37
  requirements:
24
- - - ~>
38
+ - - '>='
25
39
  - !ruby/object:Gem::Version
26
- version: 1.12.0
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rspec
29
43
  requirement: !ruby/object:Gem::Requirement