factorial-cached 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.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Yiğitcan UÇUM
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/README.md ADDED
@@ -0,0 +1,72 @@
1
+ ruby-factorial-cached
2
+ =====================
3
+
4
+ factorial-cached is a gem which aims to fasten your consecutively made factorial operations with caching. This gem was half-way done because of a little Project Euler adventure of mine. Please make any pull requests that you think will fasten the operations and i will check it out and update the gem on rubygems asap.
5
+
6
+ Usage
7
+ =====
8
+
9
+ ### Installation
10
+
11
+ ```
12
+ gem install factorial-cached
13
+ ```
14
+
15
+ ### Options
16
+
17
+ You can pass some parameters to factorial method to your needs. Above are the options and their default values.
18
+
19
+ ```ruby
20
+
21
+ # Caching
22
+
23
+ :cache_none # Doesn't caches any calculated factorial.
24
+ :cache_all # Caches all the possible invocation/iteration results. This option is not recommended if you will work with high numbers.
25
+ :cache_one # Caches only the given numbers results. (DEFAULT)
26
+
27
+ # Algorithm
28
+
29
+ :iterative # Iterative implementation of the Factorial Algorithm. Good if you will calculate high numbers.
30
+ :recursive # Recursive implementation of the Factorial Algorithm. Good if you want speed on low numbers.
31
+ :auto # Iterative if number > 100.000, Recursive if below or equal. (DEFAULT)
32
+
33
+ # Closest
34
+
35
+ :value # Returns value of the closest factorial.
36
+ :factorial # Returns closest cached factorial.
37
+
38
+ ```
39
+
40
+ ### Code
41
+
42
+ ```ruby
43
+ require 'factorial-cached'
44
+
45
+ 5.factorial # => 120 - Caches 5 factorial only.
46
+ 8.factorial(:cache_all) #=> 40320 - Caches through 6..8 factorial.
47
+ 7.factorial #=> 5040 - Returns by Dividing cached 8! / 8
48
+
49
+ Factorial::factorial(5, :iterative, :cache_all) #=> Same deal as the Integer#factorial
50
+
51
+ Factorial::closest(5) #=> 5 - Returns closest cached factorial by the given number.
52
+ Factorial::closest(5, :value) #=> 120 - Returns closest cached factorial's value by the given number.
53
+
54
+ Factorial::empty_cache() # Empties cache if you don't want to have memory issues.
55
+ Factorial::empty_cache(5..8) # Emtpies cache through 5..8 factorial.
56
+
57
+ Factorial::get_cache() # => { 0 => 1} in this case.
58
+
59
+ Factorial::toggle(:cache, :cache_none) # Toggles default of caching to none, further factorial calculations will not be cached by default.
60
+ Factorial::toggle(:algorithm, :iterative) # Togglest default algorithm to iterative algorithm.
61
+ Factorial::toggle(:closest, :value) # Closest now returns value of the factorial default.
62
+
63
+ 5.factorial => Returns 5, caches nothing.
64
+ 5.factorial(:cache_one) => Calculates 5!, caches 5! only. (This is the default behaviour of this gem)
65
+ 5.factorial => Returns 5! from cache.
66
+
67
+ ```
68
+
69
+ License
70
+ =======
71
+
72
+ MIT: [External Link to License](http://opensource.org/licenses/MIT)
data/lib/Factorial.rb~ ADDED
@@ -0,0 +1,69 @@
1
+ class Factorial
2
+
3
+ @@cache = {
4
+ 0 => 1, 1 => 1, 2 => 2, 3 => 6, 4 => 24, 5 => 120, 6 => 720, 7 => 5040, 8 => 40320, 9 => 3628800, 10 => 36288000, 11 => 39916800, 12 => 479001600, # Below 32 bit
5
+ 14 => 87178291200, 20 => 2432902008176640000, 30 => 265252859812191058636308480000000, 50 => 30414093201713378043612608166064768844377641568960512000000000000, # Below are milestones for 1-100!
6
+ 70 => 11978571669969891796072783721689098736458938142546425857555362864628009582789845319680000000000000000,
7
+ 100 => 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
8
+ };
9
+
10
+ class << self
11
+
12
+ def closest(number, option = :factorial)
13
+ close = (@@cache.keys.sort{ |x, y| (x - number).abs <=> (y - number).abs })[0];
14
+ return option == :value ? @@cache[close] : close;
15
+ end
16
+
17
+ def recursive_factorial(number, cache = :cache, close = -1)
18
+
19
+ return @@cache[number] if number == close;
20
+
21
+ if close == -1 then
22
+ close = self.closest(number);
23
+ puts "Using Cache: " + close.to_s
24
+ end
25
+
26
+ result = close < number ? number * recursive_factorial(number - 1, cache, close) : recursive_factorial(number + 1, cache, close) / (number + 1);
27
+
28
+ @@cache[number] = result if cache == :cache_all;
29
+
30
+ return result;
31
+
32
+ end
33
+
34
+ def iterative_factorial(number, cache = :cache)
35
+
36
+ closest = self.closest(number);
37
+ puts "Using Cache: " + close.to_s
38
+ loopThrough = closest < number ? ((closest + 1)..number) : ((number + 1)..closest);
39
+ result = @@cache[closest];
40
+
41
+ for i in loopThrough do
42
+
43
+ if closest < number then result *= i; else result /= i; end
44
+ @@cache[i] = result if cache == :cache_all;
45
+
46
+ end
47
+
48
+ return result;
49
+ end
50
+
51
+ def factorial(number, *options)
52
+
53
+ return @@cache[number] if @@cache.has_key?(number);
54
+ return 1 if number <= 0;
55
+
56
+ factorial = method(options.include?(:iterative) || number > 100000 ? :iterative_factorial : :recursive_factorial);
57
+ cache = options.include?(:cache_none) ? :cache_none : options.include?(:cache_all) ? :cache_all : :cache;
58
+
59
+ result = factorial.call(number, cache);
60
+
61
+ @@cache[number] = result if cache != :cache_none;
62
+
63
+ return factorial;
64
+
65
+ end
66
+
67
+ end
68
+
69
+ end
data/lib/Integer.rb~ ADDED
@@ -0,0 +1,7 @@
1
+ load(File.dirname(__FILE__) + '/Factorial.rb');
2
+
3
+ class Integer
4
+ def factorial(*options)
5
+ return Factorial::factorial(self, *options);
6
+ end
7
+ end
@@ -0,0 +1,2 @@
1
+ require 'factorial-cached/Factorial.rb'
2
+ require 'factorial-cached/Integer.rb'
File without changes
@@ -0,0 +1,93 @@
1
+ class Factorial
2
+
3
+ @@cache = {
4
+ 0 => 1, 1 => 1, 2 => 2, 3 => 6, 4 => 24, 5 => 120, 6 => 720, 7 => 5040, 8 => 40320, 9 => 3628800, 10 => 36288000, 11 => 39916800, 12 => 479001600, # Below 32 bit
5
+ 14 => 87178291200, 20 => 2432902008176640000, 30 => 265252859812191058636308480000000, 50 => 30414093201713378043612608166064768844377641568960512000000000000, # Milestones for 1-100!
6
+ 70 => 11978571669969891796072783721689098736458938142546425857555362864628009582789845319680000000000000000,
7
+ 100 => 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
8
+ };
9
+
10
+ @@default = { :cache => :cache_one, :algorithm => :recursive, :closest => :factorial };
11
+
12
+ class << self
13
+
14
+ def empty_cache( range = nil )
15
+ if range != nil then
16
+ range.each{ |key| @@cache.delete(key); };
17
+ @@cache[0] = 1;
18
+ else @@cache = {0 => 1}; end
19
+ end
20
+
21
+ def get_cache()
22
+ return @@cache;
23
+ end
24
+
25
+ def toggle(setting, default)
26
+ if setting == :cache then
27
+ @@default[:cache] = default;
28
+ elsif setting == :algorithm then
29
+ @@default[:algorithm] = default;
30
+ elsif setting == :closest then
31
+ @@default[:closest] = default;
32
+ end
33
+ end
34
+
35
+ def closest(number, option = @@default[:closest])
36
+ close = (@@cache.keys.sort{ |x, y| (x - number).abs <=> (y - number).abs })[0];
37
+ return option == :value ? @@cache[close] : close;
38
+ end
39
+
40
+ def recursive_factorial(number, cache = @@default[:cache], close = -1)
41
+
42
+ return @@cache[number] if close == number;
43
+
44
+ if close == -1 then
45
+ close = self.closest(number, :factorial);
46
+ end
47
+
48
+ result = close < number ? number * recursive_factorial(number - 1, cache, close) : recursive_factorial(number + 1, cache, close) / (number + 1);
49
+
50
+ @@cache[number] = result if cache == :cache_all;
51
+
52
+ return result;
53
+ end
54
+
55
+ def iterative_factorial(number, cache = @@default[:cache])
56
+
57
+ closest = self.closest(number, :factorial);
58
+ loopThrough = closest < number ? ((closest + 1)..number) : ((number + 1)..closest);
59
+ result = @@cache[closest];
60
+
61
+ for i in loopThrough do
62
+
63
+ if closest < number then result *= i; else result /= i; end
64
+ @@cache[i] = result if cache == :cache_all;
65
+
66
+ end
67
+
68
+ return result;
69
+ end
70
+
71
+ def factorial(number, *options)
72
+
73
+ return @@cache[number] if @@cache.has_key?(number);
74
+ return 1 if (number = number.to_i) <= 0 || !number.is_a?(Integer);
75
+
76
+ factorial = method(options.include?(:iterative) ? :iterative_factorial :
77
+ options.include?(:recursive) ? :recursive_factorial :
78
+ options.include?(:auto) ? (number > 100000 ? :iterative_factorial : :recursive_factorial) :
79
+ @@default[:algorithm] == :recursive ? :recursive_factorial :
80
+ @@default[:algorithm] == :auto ? (number > 100000 ? :iterative_factorial : recursive_factorial) : :iterative_factorial);
81
+ cache = options.include?(:cache_none) ? :cache_none : options.include?(:cache_all) ? :cache_all : options.include?(:cache_one) ? :cache_one : @@default[:cache];
82
+
83
+ result = factorial.call(number, cache);
84
+
85
+ @@cache[number] = result if cache != :cache_none;
86
+
87
+ return result;
88
+
89
+ end
90
+
91
+ end
92
+
93
+ end
@@ -0,0 +1,7 @@
1
+ require File.dirname(__FILE__) + '/Factorial.rb'
2
+
3
+ class Integer
4
+ def factorial(*options)
5
+ return Factorial::factorial(self, *options);
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require File.dirname(__FILE__) + '/Factorial.rb'
2
+
3
+ class Integer
4
+ def factorial(*options)
5
+ return Factorial::factorial(self, *options);
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,56 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: factorial-cached
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Yiğitcan UÇUM
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-02-06 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: This gem is specifically made for getting your factorial operations faster.
15
+ This gem was half made already when i decided to make it because of my needs of
16
+ factorial operations in Project Euler.
17
+ email: yigitcan@hotmail.com.tr
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - LICENSE
23
+ - README.md
24
+ - lib/factorial-cached.rb~
25
+ - lib/Factorial.rb~
26
+ - lib/factorial-cached/Integer.rb
27
+ - lib/factorial-cached/Factorial.rb
28
+ - lib/factorial-cached/Integer.rb~
29
+ - lib/Integer.rb~
30
+ - lib/factorial-cached.rb
31
+ homepage: http://rubygems.org/gems/factorial-cached
32
+ licenses:
33
+ - MIT
34
+ post_install_message:
35
+ rdoc_options: []
36
+ require_paths:
37
+ - lib
38
+ required_ruby_version: !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ! '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ requirements: []
51
+ rubyforge_project:
52
+ rubygems_version: 1.8.11
53
+ signing_key:
54
+ specification_version: 3
55
+ summary: A gem for making your factorial operations faster.
56
+ test_files: []