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 +9 -0
- data/lib/pickup.rb +25 -18
- data/lib/pickup/version.rb +1 -1
- data/spec/pickup/pickup_spec.rb +8 -8
- metadata +1 -1
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
|
data/lib/pickup.rb
CHANGED
@@ -26,23 +26,33 @@ class Pickup
|
|
26
26
|
end
|
27
27
|
|
28
28
|
class CircleIterator
|
29
|
-
|
30
|
-
@obj = obj.dup
|
31
|
-
end
|
29
|
+
attr_reader :func, :obj
|
32
30
|
|
33
|
-
|
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
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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(
|
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
|
-
|
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
|
-
|
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
|
data/lib/pickup/version.rb
CHANGED
data/spec/pickup/pickup_spec.rb
CHANGED
@@ -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", "
|
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
|