pcbr 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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