fortune 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/LICENSE +20 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/fortune.gemspec +26 -0
- data/lib/fortune.rb +71 -0
- data/lib/fortune/a.rb +14 -0
- data/lib/fortune/c.rb +14 -0
- data/lib/fortune/c_repetition.rb +11 -0
- data/lib/fortune/event.rb +30 -0
- data/lib/fortune/event_list.rb +45 -0
- data/lib/fortune/odds.rb +140 -0
- data/lib/fortune/p.rb +58 -0
- data/lib/fortune/p_abstract.rb +19 -0
- data/lib/fortune/pn.rb +16 -0
- data/lib/fortune/pn_repetition.rb +13 -0
- data/lib/fortune/version.rb +3 -0
- data/spec/fortune/a_spec.rb +13 -0
- data/spec/fortune/c_repetition_spec.rb +13 -0
- data/spec/fortune/c_spec.rb +13 -0
- data/spec/fortune/event_spec.rb +17 -0
- data/spec/fortune/odds_spec.rb +32 -0
- data/spec/fortune/p_spec.rb +54 -0
- data/spec/fortune/pn_repetition_spec.rb +13 -0
- data/spec/fortune/pn_spec.rb +16 -0
- data/spec/fortune_spec.rb +11 -0
- data/spec/hash_spec.rb +29 -0
- data/spec/math_spec.rb +12 -0
- data/spec/spec_helper.rb +12 -0
- metadata +131 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9fc004785ef01cd70f23583a76c0d36cfd7d3607
|
4
|
+
data.tar.gz: eb71d50d976e4d0a78f582e2db63dc5a6947f9c3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: df3008f56c4471c58cad733994baec963df15e064c80c8ddc0a46700417a571031c874e42e1220e4d75e1f396a962ac50cd75283d1cb30b20c3e990a9a0f4e32
|
7
|
+
data.tar.gz: 19695ff2b954f96f74ef008954690d18088d1116d13811db7dae5b54ffc634bc4fa3c05ffff2c515e9eb15c67fb082291db4d2a05185bc0e6663f819be84d10c
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color --format documentation
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2013 Fotom
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 TODO: Write your name
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Fortune
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'fortune'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install fortune
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/fortune.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'fortune/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "fortune"
|
8
|
+
spec.version = Fortune::VERSION
|
9
|
+
spec.authors = ["Malykh Oleg"]
|
10
|
+
spec.email = ["malykholeg@gmail.com"]
|
11
|
+
spec.description = %q{Ruby gem for calculate probability, odds and combinations. Mostly helpfull for gambling, e.g. Poker.}
|
12
|
+
spec.summary = %q{Lib for get changes, odds, probability and combinations for given values}
|
13
|
+
spec.homepage = "https://github.com/Fotom/Fortune"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
end
|
25
|
+
|
26
|
+
|
data/lib/fortune.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
require "fortune/version"
|
2
|
+
|
3
|
+
require 'fortune/p_abstract'
|
4
|
+
require 'fortune/a'
|
5
|
+
require 'fortune/c'
|
6
|
+
require 'fortune/p'
|
7
|
+
require 'fortune/c_repetition'
|
8
|
+
require 'fortune/event_list'
|
9
|
+
require 'fortune/event'
|
10
|
+
require 'fortune/odds'
|
11
|
+
require 'fortune/pn'
|
12
|
+
require 'fortune/pn_repetition'
|
13
|
+
|
14
|
+
module Fortune
|
15
|
+
|
16
|
+
factorial = %q{
|
17
|
+
def self.factorial(n)
|
18
|
+
return 1 if n.zero?
|
19
|
+
1.upto(n).inject(:*)
|
20
|
+
end
|
21
|
+
}
|
22
|
+
Math.module_eval(factorial)
|
23
|
+
|
24
|
+
# alias
|
25
|
+
Pnr = Pn_repetition
|
26
|
+
|
27
|
+
# Fortune::Pnr(h) || Fortune.Pnr(h)
|
28
|
+
[:Cr, :C_repetition, :C, :A, :Pnr, :Pn_repetition, :Pn].each{|c|
|
29
|
+
Fortune.module_eval(%|
|
30
|
+
def self.#{c}(h)
|
31
|
+
#{c}.calc(h)
|
32
|
+
end
|
33
|
+
|)
|
34
|
+
}
|
35
|
+
|
36
|
+
# alias
|
37
|
+
Cr = C_repetition
|
38
|
+
|
39
|
+
def self.P(*args)
|
40
|
+
P.new(*args)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
class Hash
|
46
|
+
|
47
|
+
def to_P
|
48
|
+
n = 0
|
49
|
+
self.each{|k,v| n += v.to_i}
|
50
|
+
self.each{|k,v| self[k] = Fortune::P(:m => v.to_i, :n => n)}
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_p
|
55
|
+
self.to_P.each{|k,v| self[k] = v.value}
|
56
|
+
self
|
57
|
+
end
|
58
|
+
|
59
|
+
# {:a => 1, :b => 2, ...}
|
60
|
+
def choose
|
61
|
+
Fortune::Event.select(self)
|
62
|
+
end
|
63
|
+
|
64
|
+
# {[:a, :b] => 1, [:c] => 2, ...} ||
|
65
|
+
# {10 => 1, 15 => 2, ...}
|
66
|
+
def choose_set
|
67
|
+
Fortune::P.n_select(self)
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
data/lib/fortune/a.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
module Fortune
|
2
|
+
|
3
|
+
# Permutation without repetition with select k elements (accommodation)
|
4
|
+
# example: 20 different elements and you need select 5 of them (how many ways of selection exists?)
|
5
|
+
# elements is ordered ([a,b,c] != [b,c,a])
|
6
|
+
# A.calc(:elements => 10, :select => 5)
|
7
|
+
class A < P_abstract
|
8
|
+
def initialize(h)
|
9
|
+
super(h)
|
10
|
+
self.value = Math.factorial(self.n)/Math.factorial(self.n - self.k)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
data/lib/fortune/c.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
module Fortune
|
2
|
+
|
3
|
+
# Combinations without repetition
|
4
|
+
# example: 10 different elements (students) and you need select 5 of them (how many ways of selection exists?)
|
5
|
+
# elements does not ordered ([a,b,c] == [b,c,a])
|
6
|
+
# C.calc(:elements => 10, :select => 5)
|
7
|
+
class C < P_abstract
|
8
|
+
def initialize(h)
|
9
|
+
super(h)
|
10
|
+
self.value = Math.factorial(self.n)/(Math.factorial(self.k)*Math.factorial(self.n - self.k))
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Fortune
|
2
|
+
|
3
|
+
class Event
|
4
|
+
attr_accessor :has_come, :name, :m, :n
|
5
|
+
def initialize(h = {})
|
6
|
+
@has_come = false
|
7
|
+
[:name, :n, :m].each{|k| instance_variable_set("@#{k}", h[k])}
|
8
|
+
end
|
9
|
+
def p(h = {})
|
10
|
+
P.new(:m => self.m, :n => h[:n] || self.n).value
|
11
|
+
end
|
12
|
+
def try(h = {})
|
13
|
+
@has_come = P.is(self.m, h[:n] || self.n)
|
14
|
+
self
|
15
|
+
end
|
16
|
+
def has_come?
|
17
|
+
@has_come
|
18
|
+
end
|
19
|
+
def set_come
|
20
|
+
@has_come = true
|
21
|
+
end
|
22
|
+
def self.list(h = {})
|
23
|
+
EventList.new(h).calc
|
24
|
+
end
|
25
|
+
def self.select(h = {})
|
26
|
+
Event.list(h).active.name
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Fortune
|
2
|
+
|
3
|
+
class EventList < Array
|
4
|
+
attr_accessor :sum_m, :intervals, :n
|
5
|
+
def initialize(h = {})
|
6
|
+
h.each{|name, m| self.push(Event.new({:name => name, :m => m}))}
|
7
|
+
@sum_m = 0
|
8
|
+
@intervals = {}
|
9
|
+
end
|
10
|
+
def calc
|
11
|
+
self.calc_sum_m
|
12
|
+
self.calc_intervals
|
13
|
+
self.get_n
|
14
|
+
self.set_active
|
15
|
+
self
|
16
|
+
end
|
17
|
+
def set_active
|
18
|
+
self.map{|event|
|
19
|
+
next if event.m <= 0
|
20
|
+
event.set_come if self.n >= intervals[event.name][0] && self.n <= intervals[event.name][1]
|
21
|
+
}
|
22
|
+
end
|
23
|
+
def get_n
|
24
|
+
@n = P.n(self.sum_m)
|
25
|
+
end
|
26
|
+
def calc_sum_m
|
27
|
+
self.map{|event|
|
28
|
+
next if event.m <= 0
|
29
|
+
self.sum_m += event.m
|
30
|
+
}
|
31
|
+
end
|
32
|
+
def calc_intervals
|
33
|
+
x = 0
|
34
|
+
self.map{|event|
|
35
|
+
next if event.m <= 0
|
36
|
+
self.intervals[event.name] = [x + 1, x + event.m]
|
37
|
+
x = x + event.m
|
38
|
+
}
|
39
|
+
end
|
40
|
+
def active
|
41
|
+
self.select{|event| event.has_come?}.first
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
data/lib/fortune/odds.rb
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
module Fortune
|
2
|
+
|
3
|
+
# win
|
4
|
+
class Odds
|
5
|
+
include Comparable
|
6
|
+
attr_accessor :p, :s, :k, :type
|
7
|
+
|
8
|
+
def initialize(h = {})
|
9
|
+
# TODO: check p or (s and k) exists
|
10
|
+
h[:s] ||= h[:win]
|
11
|
+
h[:k] ||= h[:lose]
|
12
|
+
[:win, :lose].each{|k| h.delete(k)}
|
13
|
+
|
14
|
+
h.each{|k,v| instance_variable_set("@#{k}", v)}
|
15
|
+
self.p = P.new(s, s + k).value unless self.p
|
16
|
+
self.calc_s_k if !self.k || !self.s
|
17
|
+
|
18
|
+
self.to_win
|
19
|
+
end
|
20
|
+
|
21
|
+
def <=>(other)
|
22
|
+
if self.p < other.p
|
23
|
+
-1
|
24
|
+
elsif self.p > other.p
|
25
|
+
1
|
26
|
+
else
|
27
|
+
0
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_i
|
32
|
+
self.s, self.k = self.s.to_i, self.k.to_i
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
def n_all
|
37
|
+
s + k
|
38
|
+
end
|
39
|
+
alias :variants :n_all
|
40
|
+
|
41
|
+
# h = {:k => int, [:fractions => true]}
|
42
|
+
def to_human(h = {:k => 7})
|
43
|
+
min_delta = nil
|
44
|
+
closest_odd = nil
|
45
|
+
|
46
|
+
Odds.human(h).each{|odd|
|
47
|
+
delta = (self.p - odd.p).abs
|
48
|
+
if !min_delta || delta < min_delta
|
49
|
+
min_delta = delta
|
50
|
+
closest_odd = odd
|
51
|
+
end
|
52
|
+
}
|
53
|
+
|
54
|
+
closest_odd
|
55
|
+
end
|
56
|
+
|
57
|
+
def is_on_win?
|
58
|
+
self.type == :on_win
|
59
|
+
end
|
60
|
+
|
61
|
+
def is_on_lose?
|
62
|
+
self.type == :on_lose
|
63
|
+
end
|
64
|
+
|
65
|
+
def to_win
|
66
|
+
self.s_to_k if self.is_on_lose?
|
67
|
+
self.type = :on_win
|
68
|
+
self
|
69
|
+
end
|
70
|
+
|
71
|
+
def s_to_k
|
72
|
+
self.s, self.k = self.k, self.s
|
73
|
+
end
|
74
|
+
|
75
|
+
def to_lose
|
76
|
+
self.s_to_k if self.is_on_win?
|
77
|
+
self.type = :on_lose
|
78
|
+
self
|
79
|
+
end
|
80
|
+
|
81
|
+
def revert
|
82
|
+
self.s_to_k
|
83
|
+
self.p = 1 - self.p
|
84
|
+
self
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.equal
|
88
|
+
Odds.new({:s => 1, :k => 1})
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.human(h)
|
92
|
+
Odds.p_human(h).values
|
93
|
+
end
|
94
|
+
|
95
|
+
def to_s
|
96
|
+
"#{self.s}:#{self.k} #{self.type} (p: #{p_obj.to_percent_string})"
|
97
|
+
end
|
98
|
+
|
99
|
+
def p_obj
|
100
|
+
P.new(self.p)
|
101
|
+
end
|
102
|
+
|
103
|
+
protected
|
104
|
+
|
105
|
+
def calc_s_k
|
106
|
+
self.s = 1
|
107
|
+
self.k = s.to_f/p.to_f - s.to_f
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
def self.p_human(h)
|
113
|
+
p_odds = {Odds.equal.p => Odds.equal}
|
114
|
+
(1..h[:k]).each{|k|
|
115
|
+
(0..k-1).each{|s|
|
116
|
+
Odds.fillup_p_human(p_odds, s, k)
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
h[:fractions] ? Odds.add_fractions(p_odds, h) : p_odds
|
121
|
+
end
|
122
|
+
|
123
|
+
def self.fillup_p_human(p_odds, s, k)
|
124
|
+
odd = Odds.new({:s => s, :k => k})
|
125
|
+
odd_dup = odd.dup.revert
|
126
|
+
p_odds[odd.p] = odd if not p_odds.has_key?(odd.p)
|
127
|
+
p_odds[odd_dup.p] = odd_dup if not p_odds.has_key?(odd_dup.p)
|
128
|
+
end
|
129
|
+
|
130
|
+
def self.add_fractions(p_odds, h)
|
131
|
+
p_odds_addons = {}
|
132
|
+
p_odds.each{|key, odd|
|
133
|
+
next if odd.k == h[:k]
|
134
|
+
Odds.fillup_p_human(p_odds_addons, odd.s, odd.k + 0.5)
|
135
|
+
}
|
136
|
+
p_odds_addons.merge(p_odds)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
data/lib/fortune/p.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
module Fortune
|
2
|
+
|
3
|
+
class P
|
4
|
+
attr_accessor :p, :m, :n
|
5
|
+
|
6
|
+
# P.new(:m => 1, :n => 10), P.new(1, 10), P.new(0.1)
|
7
|
+
def initialize(m, n_all = nil)
|
8
|
+
m, n_all = m[:m], m[:n] if m.is_a?(Hash)
|
9
|
+
raise ArgumentError.new("Error: p should be less or equal 1") if (!n_all && m > 1) || (n_all && m > n_all)
|
10
|
+
@p = m unless n_all
|
11
|
+
@p = m.to_f/n_all.to_f if n_all
|
12
|
+
@m, @n = m, n_all if n_all
|
13
|
+
end
|
14
|
+
|
15
|
+
def +(other)
|
16
|
+
P.new(self.p + other.p)
|
17
|
+
end
|
18
|
+
|
19
|
+
def *(other)
|
20
|
+
P.new(self.p * other.p)
|
21
|
+
end
|
22
|
+
|
23
|
+
def odds
|
24
|
+
Odds.new(:p => self.p)
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_percent_human
|
28
|
+
self.to_percent.round(2)
|
29
|
+
end
|
30
|
+
alias :to_human :to_percent_human
|
31
|
+
|
32
|
+
def to_percent
|
33
|
+
self.p*100
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_percent_string
|
37
|
+
'%5.2f' % [self.to_percent] + '%'
|
38
|
+
end
|
39
|
+
|
40
|
+
def value
|
41
|
+
self.p
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.is(chance, n_all)
|
45
|
+
P.n(n_all) <= chance
|
46
|
+
end
|
47
|
+
def self.n(n_all)
|
48
|
+
n_all.is_a?(Array) ? n_all.sample : rand(n_all) + 1
|
49
|
+
end
|
50
|
+
# P.n_select([1..10] => 5, [3..15] => 20, ...)
|
51
|
+
# || P.n_select(10 => 90, 5 => 10)
|
52
|
+
# || P.n_select([:a, :b] => 1, [:c] => 2)
|
53
|
+
def self.n_select(h = {})
|
54
|
+
P.n(Event.select(h))
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Fortune
|
2
|
+
|
3
|
+
# Permutations
|
4
|
+
class P_abstract
|
5
|
+
attr_accessor :value, :n, :k
|
6
|
+
|
7
|
+
def initialize(h, format = {:n => :elements, :k => :select})
|
8
|
+
raise ArgumentError.new("Error: arguments should be hash") unless h.is_a?(Hash)
|
9
|
+
self.n = h[:n] || h[format[:n]]
|
10
|
+
self.k = h[:k] || h[format[:k]]
|
11
|
+
self.value = h
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.calc(n)
|
15
|
+
self.new(n).value
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
data/lib/fortune/pn.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module Fortune
|
2
|
+
|
3
|
+
# Permutation without repetition
|
4
|
+
# example: the amount of distributions of the four teams in four places (Pn.calc(4))
|
5
|
+
# Pn.calc(5), Pn.calc(:elements => 5), Pn.calc(:elements => 5, :select => 2)
|
6
|
+
class Pn < P_abstract
|
7
|
+
|
8
|
+
def initialize(h)
|
9
|
+
h = {:n => h} unless h.is_a?(Hash)
|
10
|
+
super(h)
|
11
|
+
self.value = self.k ? A.calc(h) : Math.factorial(self.n)
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Fortune
|
2
|
+
|
3
|
+
# Permutation with repetition
|
4
|
+
# example: how many different options you can dress up if there are three sweaters two skirts and two hats (3*2*2, if all thing is equal 3, then: Pn_repetition(:n => 3, :k => 3), k - element groups, n - elements count in group)
|
5
|
+
# Pnr.calc(:groups => 10, :elements => 5)
|
6
|
+
class Pn_repetition < P_abstract
|
7
|
+
def initialize(h)
|
8
|
+
super(h, {:n => :groups, :k => :elements})
|
9
|
+
self.value = self.n**self.k
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Fortune::Event do
|
4
|
+
|
5
|
+
it "should have p" do
|
6
|
+
Fortune::Event.new(:name => :get_prize, :m => 1, :n => 5).p.should eq 0.2
|
7
|
+
end
|
8
|
+
it "certain event should be" do
|
9
|
+
Fortune::Event.new(:name => :get_prize, :m => 1, :n => 1).try.has_come?.should eq true
|
10
|
+
end
|
11
|
+
it "impossible event should not be" do
|
12
|
+
Fortune::Event.new(:name => :get_prize, :m => 0, :n => 1).try.has_come?.should eq false
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Fortune::Odds do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@odd = Fortune::Odds.new(:win => 1, :lose => 9)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "correct comparison" do
|
10
|
+
@odd.should > Fortune::Odds.new(:win => 1, :lose => 99)
|
11
|
+
end
|
12
|
+
it "calculate variants" do
|
13
|
+
@odd.n_all.should eq 10
|
14
|
+
@odd.variants.should eq 10
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "to_human" do
|
18
|
+
it "convert for 1:7 max" do
|
19
|
+
Fortune::Odds.new(:win => 400, :lose => 891).to_human.should eq Fortune::Odds.new(:win => 3, :lose => 7)
|
20
|
+
end
|
21
|
+
it "convert for 1:10 max" do
|
22
|
+
Fortune::Odds.new(:win => 400, :lose => 891).to_human(:k => 10).should eq Fortune::Odds.new(:win => 4, :lose => 9)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it "revertion" do
|
27
|
+
@odd.revert.should eq Fortune::Odds.new(:win => 9, :lose => 1)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Fortune::P do
|
4
|
+
|
5
|
+
describe "new" do
|
6
|
+
it "create by n, m params" do
|
7
|
+
Fortune::P.new(:m => 1, :n => 10).value.should eq 0.1
|
8
|
+
end
|
9
|
+
it "create by list params" do
|
10
|
+
Fortune::P.new(1, 10).value.should eq 0.1
|
11
|
+
end
|
12
|
+
it "create by probability params" do
|
13
|
+
Fortune::P.new(0.1).value.should eq 0.1
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "addition" do
|
18
|
+
it "p + p = 2p" do
|
19
|
+
(Fortune.P(0.1) + Fortune.P(0.2)).p.round(5).should eq Fortune.P(0.3).p.round(5)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "multiplication" do
|
24
|
+
it "p*p = p^2" do
|
25
|
+
(Fortune.P(0.1) * Fortune.P(0.2)).p.round(5).should eq Fortune.P(0.02).p.round(5)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "odds" do
|
30
|
+
it "calc odds for probability" do
|
31
|
+
Fortune.P(0.1).odds.should eq Fortune::Odds.new(:win => 1, :lose => 9)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it "to_percent conversation" do
|
36
|
+
Fortune.P(0.1).to_percent.should eq 10
|
37
|
+
end
|
38
|
+
it "check event is happen" do
|
39
|
+
Fortune::P.is(1,10**10).should eq false
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "n" do
|
43
|
+
it "get random element from array" do
|
44
|
+
Fortune::P.n([1,1,1]).should eq 1
|
45
|
+
end
|
46
|
+
it "get random element from range" do
|
47
|
+
Fortune::P.n(100).should < 101
|
48
|
+
Fortune::P.n(100).should > 0
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Fortune::Pn_repetition do
|
4
|
+
|
5
|
+
describe "calc" do
|
6
|
+
it "get Permutation with repetition value for 5 elements and 10 groups" do
|
7
|
+
Fortune::Pn_repetition.calc(:elements => 5, :groups => 10).should eq 100000
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Fortune::Pn do
|
4
|
+
|
5
|
+
describe "calc" do
|
6
|
+
it "get Permutation value for 5 from 10" do
|
7
|
+
Fortune::Pn.calc(:elements => 10, :select => 5).should eq 30240
|
8
|
+
end
|
9
|
+
it "get Permutation value for 5" do
|
10
|
+
Fortune::Pn.calc(:elements => 5).should eq 120
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
|
data/spec/hash_spec.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Hash do
|
4
|
+
|
5
|
+
describe "to_p" do
|
6
|
+
it "convert values to percent" do
|
7
|
+
{:a => 1, :b => 3}.to_p.should == {:a => 0.25, :b => 0.75}
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "choose" do
|
12
|
+
it "select one element" do
|
13
|
+
[:a, :b].include?({:a => 1, :b => 3}.choose).should be_true
|
14
|
+
end
|
15
|
+
it "select by element weight" do
|
16
|
+
{:a => 1.0/10**5, :b => 1*10**10, :c => 1.0/10**10}.choose.should == :b
|
17
|
+
end
|
18
|
+
it "select one element by weight" do
|
19
|
+
{:a => 1, :b => 0, :c => 0}.choose.should == :a
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "choose_set" do
|
24
|
+
it "get one from set" do
|
25
|
+
[:a, :b, :c].include?({[:a, :b, :c] => 1, [:d] => 0}.choose_set).should == true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
data/spec/math_spec.rb
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
|
4
|
+
require 'rspec'
|
5
|
+
require 'fortune'
|
6
|
+
|
7
|
+
# Requires supporting files with custom matchers and macros, etc,
|
8
|
+
# in ./support/ and its subdirectories.
|
9
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
10
|
+
|
11
|
+
RSpec.configure do |config|
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fortune
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Malykh Oleg
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-12-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Ruby gem for calculate probability, odds and combinations. Mostly helpfull
|
56
|
+
for gambling, e.g. Poker.
|
57
|
+
email:
|
58
|
+
- malykholeg@gmail.com
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- .gitignore
|
64
|
+
- .rspec
|
65
|
+
- Gemfile
|
66
|
+
- LICENSE
|
67
|
+
- LICENSE.txt
|
68
|
+
- README.md
|
69
|
+
- Rakefile
|
70
|
+
- fortune.gemspec
|
71
|
+
- lib/fortune.rb
|
72
|
+
- lib/fortune/a.rb
|
73
|
+
- lib/fortune/c.rb
|
74
|
+
- lib/fortune/c_repetition.rb
|
75
|
+
- lib/fortune/event.rb
|
76
|
+
- lib/fortune/event_list.rb
|
77
|
+
- lib/fortune/odds.rb
|
78
|
+
- lib/fortune/p.rb
|
79
|
+
- lib/fortune/p_abstract.rb
|
80
|
+
- lib/fortune/pn.rb
|
81
|
+
- lib/fortune/pn_repetition.rb
|
82
|
+
- lib/fortune/version.rb
|
83
|
+
- spec/fortune/a_spec.rb
|
84
|
+
- spec/fortune/c_repetition_spec.rb
|
85
|
+
- spec/fortune/c_spec.rb
|
86
|
+
- spec/fortune/event_spec.rb
|
87
|
+
- spec/fortune/odds_spec.rb
|
88
|
+
- spec/fortune/p_spec.rb
|
89
|
+
- spec/fortune/pn_repetition_spec.rb
|
90
|
+
- spec/fortune/pn_spec.rb
|
91
|
+
- spec/fortune_spec.rb
|
92
|
+
- spec/hash_spec.rb
|
93
|
+
- spec/math_spec.rb
|
94
|
+
- spec/spec_helper.rb
|
95
|
+
homepage: https://github.com/Fotom/Fortune
|
96
|
+
licenses:
|
97
|
+
- MIT
|
98
|
+
metadata: {}
|
99
|
+
post_install_message:
|
100
|
+
rdoc_options: []
|
101
|
+
require_paths:
|
102
|
+
- lib
|
103
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - '>='
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - '>='
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
requirements: []
|
114
|
+
rubyforge_project:
|
115
|
+
rubygems_version: 2.1.11
|
116
|
+
signing_key:
|
117
|
+
specification_version: 4
|
118
|
+
summary: Lib for get changes, odds, probability and combinations for given values
|
119
|
+
test_files:
|
120
|
+
- spec/fortune/a_spec.rb
|
121
|
+
- spec/fortune/c_repetition_spec.rb
|
122
|
+
- spec/fortune/c_spec.rb
|
123
|
+
- spec/fortune/event_spec.rb
|
124
|
+
- spec/fortune/odds_spec.rb
|
125
|
+
- spec/fortune/p_spec.rb
|
126
|
+
- spec/fortune/pn_repetition_spec.rb
|
127
|
+
- spec/fortune/pn_spec.rb
|
128
|
+
- spec/fortune_spec.rb
|
129
|
+
- spec/hash_spec.rb
|
130
|
+
- spec/math_spec.rb
|
131
|
+
- spec/spec_helper.rb
|