pickup 0.0.6 → 0.0.7
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.
- 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
|