pickup 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -83,6 +83,15 @@ pickup.pick
83
83
  #=> "sturgeon"
84
84
  ```
85
85
 
86
+ ### Custom probability function
87
+
88
+ You can define your own function. So in case of `f(weight)=weight^10` most possible result will be "minnow", because `20^10` is `2^10` more possible then "gudgeon"
89
+ ```ruby
90
+ pickup = Pickup.new(pond)
91
+ pickup.pick(10){ |v| v**10 }
92
+ #=> ["minnow", "minnow", "minnow", "minnow", "minnow", "minnow", "minnow", "minnow", "minnow", "minnow"]
93
+ ```
94
+
86
95
  ## Contributing
87
96
 
88
97
  1. Fork it
@@ -26,23 +26,33 @@ class Pickup
26
26
  end
27
27
 
28
28
  class CircleIterator
29
- def initialize(obj)
30
- @obj = obj.dup
31
- end
29
+ attr_reader :func, :obj
32
30
 
33
- def each
31
+ def initialize(obj, func)
32
+ @obj = obj.dup
33
+ @func = func
34
+ end
35
+
36
+ def each
37
+ mx = max
38
+ until obj.empty?
34
39
  start = 0
35
- until @obj.empty?
36
- @obj.each do |item, weight|
37
- start += weight
38
- if yield([item, start])
39
- @obj.delete item
40
- end
40
+ obj.each do |item, weight|
41
+ val = func.call(weight)
42
+ start += val
43
+ if yield([item, start, mx])
44
+ obj.delete item
45
+ mx = max
41
46
  end
42
47
  end
43
48
  end
44
49
  end
45
50
 
51
+ def max
52
+ obj.inject(0){ |mx, item| mx += func.call(item[1]) }
53
+ end
54
+ end
55
+
46
56
  class MappedList
47
57
  attr_reader :list, :func, :uniq
48
58
 
@@ -54,7 +64,7 @@ class Pickup
54
64
  end
55
65
 
56
66
  def each(&blk)
57
- CircleIterator.new(@list).each do |item|
67
+ CircleIterator.new(@list, func).each do |item|
58
68
  if uniq
59
69
  true if yield item
60
70
  else
@@ -65,7 +75,7 @@ class Pickup
65
75
 
66
76
  def random(count)
67
77
  raise "List is shorter then count of items you want to get" if uniq && list.size < count
68
- nums = count.times.map{ rand(func.call(max)) }.sort
78
+ nums = count.times.map{ rand(max) }.sort
69
79
  get_random_items(nums)
70
80
  end
71
81
 
@@ -73,10 +83,9 @@ class Pickup
73
83
  next_num = Proc.new{ nums.shift }
74
84
  current_num = next_num.call
75
85
  items = []
76
- each do |item, counter|
86
+ each do |item, counter, mx|
77
87
  break unless current_num
78
- val = func.call(counter)
79
- if val > current_num
88
+ if counter%(mx+1) > current_num%mx
80
89
  items << item
81
90
  current_num = next_num.call
82
91
  true
@@ -86,9 +95,7 @@ class Pickup
86
95
  end
87
96
 
88
97
  def max
89
- @max ||= begin
90
- list.inject(0){ |mx, item| mx += item[1]}
91
- end
98
+ list.inject(0){ |mx, item| mx += func.call(item[1]) }
92
99
  end
93
100
  end
94
101
  end
@@ -1,3 +1,3 @@
1
1
  class Pickup
2
- VERSION = "0.0.6"
2
+ VERSION = "0.0.7"
3
3
  end
@@ -4,13 +4,13 @@ require 'spec_helper'
4
4
  describe Pickup do
5
5
  before do
6
6
  @list = {
7
- "selmon" => 1,
8
- "carp" => 4,
9
- "crucian" => 3,
10
- "herring" => 6,
11
- "sturgeon" => 8,
12
- "gudgeon" => 10,
13
- "minnow" => 20
7
+ "selmon" => 1, # 1
8
+ "carp" => 4, # 5
9
+ "crucian" => 3, # 8
10
+ "herring" => 6, # 14
11
+ "sturgeon" => 8, # 22
12
+ "gudgeon" => 10, # 32
13
+ "minnow" => 20 # 52
14
14
  }
15
15
  @func = Proc.new{ |a| a }
16
16
  @pickup = Pickup.new(@list)
@@ -43,7 +43,7 @@ describe Pickup do
43
43
  end
44
44
 
45
45
  it "should return item from the beginning after end of list for uniq pickup" do
46
- @ml.get_random_items([20, 20, 20, 20]).must_equal ["sturgeon", "gudgeon", "minnow", "selmon"]
46
+ @ml.get_random_items([20, 20, 20, 20]).must_equal ["sturgeon", "gudgeon", "minnow", "crucian"]
47
47
  end
48
48
 
49
49
  it "should return right max" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pickup
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: