pickup 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/lib/pickup.rb CHANGED
@@ -25,9 +25,26 @@ class Pickup
25
25
  end
26
26
  end
27
27
 
28
+ class CircleIterator
29
+ def initialize(obj)
30
+ @obj = obj.dup
31
+ end
32
+
33
+ def each
34
+ 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
41
+ end
42
+ end
43
+ end
44
+ end
45
+
28
46
  class MappedList
29
- include Enumerable
30
- attr_reader :list, :func, :uniq, :max
47
+ attr_reader :list, :func, :uniq
31
48
 
32
49
  def initialize(list, func, uniq=false)
33
50
  @func = func
@@ -37,43 +54,18 @@ class Pickup
37
54
  end
38
55
 
39
56
  def each(&blk)
40
- item_iterator = next_item
41
- item = nil
42
- drop = false
43
- while true do
44
- item ||= item_iterator.call(drop)
45
- drop = false
57
+ CircleIterator.new(@list).each do |item|
46
58
  if uniq
47
- drop = true if yield item
48
- item = nil
59
+ true if yield item
49
60
  else
50
- item = nil unless yield item
61
+ nil while yield(item)
51
62
  end
52
63
  end
53
64
  end
54
65
 
55
- def next_item
56
- dup = list.dup
57
- start = 0
58
- enum = dup.to_enum
59
- item = nil
60
- Proc.new do |drop|
61
- dup.delete item if drop
62
- item = begin
63
- enum.next
64
- rescue StopIteration => e
65
- enum = dup.to_enum
66
- enum.next
67
- end
68
- start += item[1]
69
- item[1] = start
70
- item
71
- end
72
- end
73
-
74
66
  def random(count)
75
67
  raise "List is shorter then count of items you want to get" if uniq && list.size < count
76
- nums = count.times.map{ func.call(rand(max)) }.sort
68
+ nums = count.times.map{ rand(func.call(max)) }.sort
77
69
  get_random_items(nums)
78
70
  end
79
71
 
@@ -92,5 +84,11 @@ class Pickup
92
84
  end
93
85
  items
94
86
  end
87
+
88
+ def max
89
+ @max ||= begin
90
+ list.inject(0){ |mx, item| mx += item[1]}
91
+ end
92
+ end
95
93
  end
96
94
  end
@@ -1,3 +1,3 @@
1
1
  class Pickup
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
@@ -38,9 +38,17 @@ describe Pickup do
38
38
  @ml2.get_random_items([0]).first.must_equal "selmon"
39
39
  end
40
40
 
41
+ it "should return crucian 3 times for uniq pickup" do
42
+ @ml2.get_random_items([7, 7, 7]).must_equal ["crucian", "crucian", "crucian"]
43
+ end
44
+
41
45
  it "should return item from the beginning after end of list for uniq pickup" do
42
46
  @ml.get_random_items([20, 20, 20, 20]).must_equal ["sturgeon", "gudgeon", "minnow", "selmon"]
43
47
  end
48
+
49
+ it "should return right max" do
50
+ @ml.max.must_equal 52
51
+ end
44
52
  end
45
53
 
46
54
  it "should take 7 different fish" do
@@ -51,4 +59,9 @@ describe Pickup do
51
59
  it "should raise an exception" do
52
60
  proc{ items = @pickup2.pick(8) }.must_raise RuntimeError
53
61
  end
62
+
63
+ it "should return include most wegtful item (but not always - sometimes it will fail)" do
64
+ items = @pickup2.pick(2){ |v| v**20 }
65
+ (items.include? "minnow").must_equal true
66
+ end
54
67
  end
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.5
4
+ version: 0.0.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-01 00:00:00.000000000 Z
12
+ date: 2012-06-04 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Pickup helps you to pick item from collection by it's weight/probability
15
15
  email:
@@ -48,7 +48,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
48
48
  version: '0'
49
49
  requirements: []
50
50
  rubyforge_project:
51
- rubygems_version: 1.8.24
51
+ rubygems_version: 1.8.23
52
52
  signing_key:
53
53
  specification_version: 3
54
54
  summary: Pickup helps you to pick item from collection by it's weight/probability