magician 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.rspec +1 -0
- data/.travis.yml +8 -0
- data/Gemfile +14 -0
- data/LICENSE.txt +20 -0
- data/README.md +18 -0
- data/Rakefile +42 -0
- data/VERSION +1 -0
- data/lib/magician.rb +3 -0
- data/lib/magician/array.rb +83 -0
- data/lib/magician/integer.rb +66 -0
- data/lib/magician/math.rb +120 -0
- data/lib/magician/numeric.rb +17 -0
- data/lib/magician/shortcuts.rb +7 -0
- data/lib/magician/string.rb +12 -0
- data/spec/array_spec.rb +55 -0
- data/spec/integer_spec.rb +45 -0
- data/spec/math_spec.rb +77 -0
- data/spec/numeric_spec.rb +11 -0
- data/spec/shortcuts_spec.rb +10 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/string_spec.rb +14 -0
- metadata +168 -0
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
source :rubygems
|
2
|
+
|
3
|
+
# Add dependencies required to use your gem here.
|
4
|
+
|
5
|
+
# Add dependencies to develop your gem here.
|
6
|
+
# Include everything needed to run rake, tests, features, etc.
|
7
|
+
group :development do
|
8
|
+
gem 'rspec', '~> 2.12.0'
|
9
|
+
gem 'yard', '~> 0.7'
|
10
|
+
gem 'rdoc', '~> 3.12'
|
11
|
+
gem 'bundler'
|
12
|
+
gem 'jeweler', '~> 1.8.4'
|
13
|
+
gem 'simplecov'
|
14
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Nicolas McCurdy
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# magician [![Build Status](https://secure.travis-ci.org/thenickperson/magician.png?branch=master)](http://travis-ci.org/thenickperson/magician) [![Dependency Status](https://gemnasium.com/thenickperson/magician.png)](https://gemnasium.com/thenickperson/magician) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/thenickperson/magician)
|
2
|
+
|
3
|
+
A suite of handy methods for doing calculations in irb.
|
4
|
+
|
5
|
+
## Contributing to magician
|
6
|
+
|
7
|
+
- Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
8
|
+
- Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
9
|
+
- Fork the project.
|
10
|
+
- Start a feature/bugfix branch.
|
11
|
+
- Commit and push until you are happy with your contribution.
|
12
|
+
- Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
13
|
+
- Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
14
|
+
|
15
|
+
## Copyright
|
16
|
+
|
17
|
+
Copyright (c) 2012 Nicolas McCurdy. See LICENSE.txt for
|
18
|
+
further details.
|
data/Rakefile
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "magician"
|
18
|
+
gem.homepage = "http://github.com/thenickperson/magician"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = "A suite of handy methods for doing calculations in irb."
|
21
|
+
gem.description = "A suite of handy methods for doing calculations in irb."
|
22
|
+
gem.email = "thenickperson@gmail.com"
|
23
|
+
gem.authors = ["Nicolas McCurdy"]
|
24
|
+
# dependencies defined in Gemfile
|
25
|
+
end
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
27
|
+
|
28
|
+
require 'rspec/core'
|
29
|
+
require 'rspec/core/rake_task'
|
30
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
31
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
32
|
+
end
|
33
|
+
|
34
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
35
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
36
|
+
spec.rcov = true
|
37
|
+
end
|
38
|
+
|
39
|
+
task :default => :spec
|
40
|
+
|
41
|
+
require 'yard'
|
42
|
+
YARD::Rake::YardocTask.new
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/lib/magician.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
# Magician's extensions to the Array class.
|
2
|
+
class Array
|
3
|
+
|
4
|
+
# Gets the sum of the numbers in the array. The sum of an empty array is 0.
|
5
|
+
#
|
6
|
+
# @return [Numeric] the sum of the numbers in the array
|
7
|
+
def sum
|
8
|
+
return 0 if self.empty?
|
9
|
+
inject(:+)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Gets the product of the numbers in the array. The product of an empty array
|
13
|
+
# is 1.
|
14
|
+
#
|
15
|
+
# @return [Numeric] the product of the numbers in the array
|
16
|
+
def product
|
17
|
+
return 1 if self.empty?
|
18
|
+
inject(:*)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Gets the range of the numbers in the array (maximum - minimum). The range of
|
22
|
+
# an empty array is nil.
|
23
|
+
#
|
24
|
+
# @return [Numeric] the range of the numbers in the array
|
25
|
+
def range
|
26
|
+
return nil if self.empty?
|
27
|
+
max - min
|
28
|
+
end
|
29
|
+
|
30
|
+
# Gets the mean (average) of the numbers in the array. The mean of an empty
|
31
|
+
# array is nil.
|
32
|
+
#
|
33
|
+
# @return [Float] the mean (average) of the numbers in the array
|
34
|
+
def mean
|
35
|
+
return nil if self.empty?
|
36
|
+
sum.to_f / size
|
37
|
+
end
|
38
|
+
|
39
|
+
# Gets the median of the numbers in the array (the value in the middle of a
|
40
|
+
# sorted version of the array). If the array has an even length, the middle
|
41
|
+
# two values are averaged. The median of an empty array is nil.
|
42
|
+
#
|
43
|
+
# @return [Numeric] the median of the numbers in the array
|
44
|
+
def median
|
45
|
+
return nil if self.empty?
|
46
|
+
sorted = sort
|
47
|
+
if sorted.length.odd?
|
48
|
+
self[length/2]
|
49
|
+
else
|
50
|
+
(self[length/2-1] + self[length/2]) / 2.0
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Gets the mode(s) of the items in the array (the item(s) that occur(s) most
|
55
|
+
# frequently). The mode of an empty array is nil.
|
56
|
+
#
|
57
|
+
# @return [Array] an array of all of the items in the array that occur the
|
58
|
+
# most freqeuntly (they must all have the same number of occurences)
|
59
|
+
def mode
|
60
|
+
return nil if self.empty?
|
61
|
+
occ = occurences
|
62
|
+
max_occ = occ.values.max
|
63
|
+
occ.select { |key, value| value == max_occ }.keys
|
64
|
+
end
|
65
|
+
|
66
|
+
# Gets a hash table with the number of occurences of each item from the
|
67
|
+
# original array. The keys are the items from the original array, and the
|
68
|
+
# values are integers counting the number of occurences of the associated key
|
69
|
+
# values.
|
70
|
+
#
|
71
|
+
# @return [Hash] a hash table of the occurences of each item from the original
|
72
|
+
# array
|
73
|
+
def occurences
|
74
|
+
occurences = {}
|
75
|
+
self.each { |item| occurences[item] = 0 }
|
76
|
+
self.each { |item| occurences[item] += 1 }
|
77
|
+
occurences
|
78
|
+
end
|
79
|
+
|
80
|
+
# Alias average to mean.
|
81
|
+
alias :average :mean
|
82
|
+
|
83
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# Magician's extensions to the Integer class.
|
2
|
+
class Integer
|
3
|
+
|
4
|
+
# Gets all of the factors of the current integer. If the current integer is
|
5
|
+
# negative, it will be treated as if it were positive (so the results will
|
6
|
+
# never contain negative integers).
|
7
|
+
#
|
8
|
+
# @return [Array] an array of all of the factors of the current integer (in
|
9
|
+
# order, including 1 and the integer itself)
|
10
|
+
def factors
|
11
|
+
return nil if self == 0
|
12
|
+
return [1] if self.abs == 1
|
13
|
+
#first half
|
14
|
+
factors = []
|
15
|
+
for i in 1..self.abs
|
16
|
+
if self.abs % i == 0
|
17
|
+
if i < self.abs/i
|
18
|
+
factors << i
|
19
|
+
else break
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
#second half
|
24
|
+
factors_old = factors.dup
|
25
|
+
until factors_old.length == 0
|
26
|
+
factors << self.abs/factors_old.pop
|
27
|
+
end
|
28
|
+
return factors
|
29
|
+
end
|
30
|
+
|
31
|
+
# Gets the factorial of the integer, which is equivalent to the product of all
|
32
|
+
# integers from 1 to the integer (inclusive). When the integer is 0, it is
|
33
|
+
# equivalent to 1.
|
34
|
+
#
|
35
|
+
# @return [Integer] factorial of the integer
|
36
|
+
def factorial
|
37
|
+
return 1 if self == 0
|
38
|
+
(1..self).inject(:*)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns true if the integer is prime (that is, if it is not divisible by any
|
42
|
+
# integer between 1 and the integer itself, exclusive). 0 and 1 are not prime
|
43
|
+
# numbers, though 2 is prime. Negative numbers are never considered prime in
|
44
|
+
# this implementation.
|
45
|
+
#
|
46
|
+
# @return [Boolean] true if the integer is prime
|
47
|
+
def prime?
|
48
|
+
return false if self <= 1
|
49
|
+
for i in 2..Math.sqrt(self)
|
50
|
+
return false if self % i == 0
|
51
|
+
end
|
52
|
+
return true
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns true if the integer is evenly divisible by n. If n is 0, it returns
|
56
|
+
# false, since numbers cannot be divided by 0 in real number arithmetic.
|
57
|
+
#
|
58
|
+
# @param [Numeric] n the number the integer should be divided by
|
59
|
+
#
|
60
|
+
# @return [Boolean] true if the integer is evenly divisible by n
|
61
|
+
def divisible? n
|
62
|
+
return false if n.zero?
|
63
|
+
(self % n).zero?
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# Magician's extensions to the Math module.
|
2
|
+
module Math
|
3
|
+
|
4
|
+
# If we don't do this, our new methods won't get added onto Math.
|
5
|
+
extend self
|
6
|
+
|
7
|
+
# Solves a quadratic formula of the form "ax^2+bx+c=0" for x, where a is not
|
8
|
+
# 0. It asks for the three coefficients of the function (a, b, and c), and
|
9
|
+
# returns the two possible values for x.
|
10
|
+
#
|
11
|
+
# @param [Numeric] a the first coefficient (must not be 0)
|
12
|
+
# @param [Numeric] b the second coefficient
|
13
|
+
# @param [Numeric] c the third coefficient
|
14
|
+
#
|
15
|
+
# @return [Array] a sorted array of two Floats, the two possible values for x
|
16
|
+
def quadratic(a, b, c)
|
17
|
+
return nil if a.zero?
|
18
|
+
left = -b
|
19
|
+
right = Math.sqrt(b**2 - 4*a*c)
|
20
|
+
bottom = 2*a
|
21
|
+
[ (left+right)/bottom, (left-right)/bottom ].sort
|
22
|
+
end
|
23
|
+
|
24
|
+
# The number of size k ordered subsets of a set of size n. Equivalent to
|
25
|
+
# n!/(n-k)!. Returns nil if either is negative, or if n < k.
|
26
|
+
#
|
27
|
+
# @param [Integer] n the size of the set to pick from
|
28
|
+
# @param [Integer] k the size of the ordered subsets
|
29
|
+
#
|
30
|
+
# @return [Integer] the number of permutations
|
31
|
+
def permutations(n, k)
|
32
|
+
return nil if n < 0 or k < 0 or n < k
|
33
|
+
return n.factorial / (n-k).factorial
|
34
|
+
end
|
35
|
+
|
36
|
+
# The number of size k unordered subsets of a set of size n. Equivalent to
|
37
|
+
# n!/(k!(n-k)!). Returns nil if either is negative, or if n < k.
|
38
|
+
#
|
39
|
+
# @param [Integer] n the size of the set to pick from
|
40
|
+
# @param [Integer] k the size of the unordered subsets
|
41
|
+
#
|
42
|
+
# @return [Integer] the number of combinations
|
43
|
+
def combinations(n, k)
|
44
|
+
return nil if n < 0 or k < 0 or n < k
|
45
|
+
return n.factorial / (k.factorial * (n-k).factorial)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Get the number of steps it takes to get from integer n to 1 using the
|
49
|
+
# Collatz Conjecture (set http://en.wikipedia.org/wiki/Collatz_conjecture).
|
50
|
+
#
|
51
|
+
# @param [Integer] n the number to put into the Collatz Conjecture initially
|
52
|
+
# @param [Integer] depth the number of steps that have passed so far (should
|
53
|
+
# not be modified unless this is being cached carefully)
|
54
|
+
#
|
55
|
+
# @return [Integer] the number of steps it takes to get from integer n to 1
|
56
|
+
# using the Collatz Conjecture (the depth)
|
57
|
+
def collatz(n, depth=0)
|
58
|
+
return nil if n < 1
|
59
|
+
if n == 1
|
60
|
+
return depth
|
61
|
+
elsif n % 2 == 0
|
62
|
+
depth += 1
|
63
|
+
return collatz(n/2, depth)
|
64
|
+
else
|
65
|
+
depth += 1
|
66
|
+
return collatz(3*n + 1, depth)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Using the Pythagorean theorem, gets c (the length of the hypotenuse) when a
|
71
|
+
# and b (the lengths of the other sides of a triangle) are given. Returns nil
|
72
|
+
# if either a or b is negative.
|
73
|
+
#
|
74
|
+
# @param [Numeric] a the length of the first side of the triangle
|
75
|
+
# @param [Numeric] b the length of the second side of the triangle
|
76
|
+
#
|
77
|
+
# @return [Float] the length of the hypotenuse of the triangle
|
78
|
+
def hypotenuse(a, b)
|
79
|
+
[a,b].each do |n|
|
80
|
+
return nil if n < 0
|
81
|
+
end
|
82
|
+
Math.sqrt(a**2 + b**2)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Returns true if the three given numbers are positive integers that form a
|
86
|
+
# Pythagorean triplet (that is, if a^2+b^2=c^2). C must be the last parameter.
|
87
|
+
#
|
88
|
+
# @param [Integer] a the length of the first side of the triangle
|
89
|
+
# @param [Integer] b the length of the second side of the triangle
|
90
|
+
# @param [Integer] c the length of the hypotenuse of the triangle
|
91
|
+
#
|
92
|
+
# @return [Boolean] true if the three numbers form a Pythagorean triplet
|
93
|
+
def triplet?(a, b, c)
|
94
|
+
inputs_are_valid = true
|
95
|
+
[a,b,c].each do |n|
|
96
|
+
inputs_are_valid = false if n < 1 or not n.class <= Integer
|
97
|
+
end
|
98
|
+
return false unless inputs_are_valid
|
99
|
+
a**2 + b**2 == c**2
|
100
|
+
end
|
101
|
+
|
102
|
+
# Calculates a series of Fibonacci numbers of a specified length. Returns nil
|
103
|
+
# if a negative length is given.
|
104
|
+
#
|
105
|
+
# @param [Integer] length the length of the Fibonacci series that should be
|
106
|
+
# returned
|
107
|
+
#
|
108
|
+
# @return [Array] a Fibonacci series of Integers with the specified length
|
109
|
+
# (ordered)
|
110
|
+
def fibs length
|
111
|
+
return nil if length < 0
|
112
|
+
terms = []
|
113
|
+
until terms.length == length do
|
114
|
+
at_beginning = [0,1].include? terms.length
|
115
|
+
terms << ( at_beginning ? 1 : terms[-2] + terms[-1] )
|
116
|
+
end
|
117
|
+
terms
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Magician's extensions to the Numeric class (affects Integers and Floats).
|
2
|
+
class Numeric
|
3
|
+
|
4
|
+
# Performs self.to_s[selection].to_i on the number. Note that for floats, the
|
5
|
+
# decimal counts as a digit within the string.
|
6
|
+
# TODO: Let this intelligently convert back to an Integer or Float.
|
7
|
+
#
|
8
|
+
# @param [Range] selection the selection/range to get from the number (you can
|
9
|
+
# use anything that works with the [] syntax)
|
10
|
+
#
|
11
|
+
# @return [Integer] substring of the number (using []), converted to an
|
12
|
+
# Integer
|
13
|
+
def digits selection
|
14
|
+
self.to_s[selection].to_i
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# Magician's extensions to the String class.
|
2
|
+
class String
|
3
|
+
|
4
|
+
# Returns true if the string is a palindrome (meaning it is the same forward
|
5
|
+
# and backward).
|
6
|
+
#
|
7
|
+
# @return [Boolean] true if the string is a palindrome
|
8
|
+
def palindrome?
|
9
|
+
self == reverse
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
data/spec/array_spec.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Array do
|
4
|
+
|
5
|
+
it 'should get the sum of a list' do
|
6
|
+
[].sum.should == 0
|
7
|
+
[1].sum.should == 1
|
8
|
+
[1, 2, 3, 4].sum.should == 10
|
9
|
+
[-4, 0, 5].sum.should == 1
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should get the product of a list' do
|
13
|
+
[].product.should == 1
|
14
|
+
[1].product.should == 1
|
15
|
+
[5, 7, 2].product.should == 70
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should get the range of a list' do
|
19
|
+
[].range.should == nil
|
20
|
+
[4].range.should == 0
|
21
|
+
[5, 1, 10].range.should == 9
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should get the mean of a list' do
|
25
|
+
[].mean.should == nil
|
26
|
+
[4].mean.should == 4
|
27
|
+
[-3, 0, 6].mean.should == 1
|
28
|
+
[1, 2, 3, 4, 5].mean.should == 3
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should get the median of a list' do
|
32
|
+
[].median.should == nil
|
33
|
+
[4].median.should == 4.0
|
34
|
+
[2, 1, 3, 5, 4].median.should == 3.0
|
35
|
+
[1, 2, 3, 4].median.should == 2.5
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should get the mode of a list' do
|
39
|
+
[].mode.should == nil
|
40
|
+
[4].mode.should == [4]
|
41
|
+
[1, 2, 1, 3, 1, 4].mode.should == [1]
|
42
|
+
[1, 1, 1, 2, 2, 2, 3].mode.should == [1, 2]
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should get a hash with the number of occurences of items in a list' do
|
46
|
+
[].occurences.should == {}
|
47
|
+
[4].occurences.should == { 4=>1 }
|
48
|
+
[1, 2, 2, 5].occurences.should == { 1=>1, 2=>2, 5=>1 }
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should let Array#average be used as an alias to Array#mean' do
|
52
|
+
[4].average.should == 4.0
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Integer do
|
4
|
+
|
5
|
+
it 'should get the factors of an integer' do
|
6
|
+
0.factors.should == nil
|
7
|
+
1.factors.should == [1]
|
8
|
+
6.factors.should == [1, 2, 3, 6]
|
9
|
+
7.factors.should == [1, 7]
|
10
|
+
-1.factors.should == [1]
|
11
|
+
-6.factors.should == [1, 2, 3, 6]
|
12
|
+
-7.factors.should == [1, 7]
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should get the factorial of an integer' do
|
16
|
+
0.factorial.should == 1
|
17
|
+
1.factorial.should == 1
|
18
|
+
-1.factorial.should == nil
|
19
|
+
5.factorial.should == 120
|
20
|
+
10.factorial.should == 3_628_800
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should determine if an integer is prime' do
|
24
|
+
0.prime?.should be_false
|
25
|
+
1.prime?.should be_false
|
26
|
+
2.prime?.should be_true
|
27
|
+
5.prime?.should be_true
|
28
|
+
6.prime?.should be_false
|
29
|
+
-1.prime?.should be_false
|
30
|
+
-2.prime?.should be_false
|
31
|
+
-5.prime?.should be_false
|
32
|
+
-6.prime?.should be_false
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should determine if an integer is divisible by another number' do
|
36
|
+
0.divisible?(5).should be_true
|
37
|
+
1.divisible?(6).should be_false
|
38
|
+
-1.divisible?(1).should be_true
|
39
|
+
12.divisible?(6).should be_true
|
40
|
+
6.divisible?(5).should be_false
|
41
|
+
9.divisible?(1.5).should be_true
|
42
|
+
10.divisible?(0).should be_false
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
data/spec/math_spec.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Math do
|
4
|
+
|
5
|
+
it 'should solve a quadratic formula' do
|
6
|
+
Math.quadratic(1, 2, 1).should == [-1.0, -1.0]
|
7
|
+
Math.quadratic(1, 1, 0).should == [-1.0, 0.0]
|
8
|
+
Math.quadratic(1, 0, 0).should == [0.0, 0.0]
|
9
|
+
Math.quadratic(0, 1, 2).should == nil
|
10
|
+
#Math.quadratic(1, 2, 3).should == 'change me'
|
11
|
+
#Math.quadratic(-1, -2, -3).should == 'change me'
|
12
|
+
#Math.quadratic(1, 1, 1).should == 'change me'
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should get the number of permutations with n and k' do
|
16
|
+
Math.permutations(10, 5).should == 30_240
|
17
|
+
Math.permutations(5, 5).should == 120
|
18
|
+
Math.permutations(5, 0).should == 1
|
19
|
+
Math.permutations(0, 5).should == nil
|
20
|
+
Math.permutations(0, 0).should == 1
|
21
|
+
Math.permutations(5, 10).should == nil
|
22
|
+
Math.permutations(-5, 5).should == nil
|
23
|
+
Math.permutations(5, -5).should == nil
|
24
|
+
Math.permutations(-5, -5).should == nil
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should get the number of combinations with n and k' do
|
28
|
+
Math.combinations(10, 5).should == 252
|
29
|
+
Math.combinations(5, 10).should == nil
|
30
|
+
Math.combinations(5, 5).should == 1
|
31
|
+
Math.combinations(5, 0).should == 1
|
32
|
+
Math.combinations(0, 5).should == nil
|
33
|
+
Math.combinations(0, 0).should == 1
|
34
|
+
Math.combinations(-5, 5).should == nil
|
35
|
+
Math.combinations(5, -5).should == nil
|
36
|
+
Math.combinations(-5, -5).should == nil
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should get the number of steps to finish the Collatz Conjecture' do
|
40
|
+
Math.collatz(-1).should == nil
|
41
|
+
Math.collatz(0).should == nil
|
42
|
+
Math.collatz(1).should == 0
|
43
|
+
Math.collatz(2).should == 1
|
44
|
+
Math.collatz(7).should == 16
|
45
|
+
Math.collatz(100).should == 25
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should get the length of a hypotenuse with the Pythagorean theorem' do
|
49
|
+
Math.hypotenuse(0, 0).should == 0
|
50
|
+
Math.hypotenuse(Math.sqrt(5), 2).should == 3
|
51
|
+
Math.hypotenuse(1, 1).should == Math.sqrt(2)
|
52
|
+
Math.hypotenuse(5, -5).should be_nil
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should determine if three given numbers form a Pythagorean triplet' do
|
56
|
+
Math.triplet?(3, 4, 5).should be_true
|
57
|
+
Math.triplet?(5, 12, 13).should be_true
|
58
|
+
Math.triplet?(7, 24, 25).should be_true
|
59
|
+
Math.triplet?(8, 15, 17).should be_true
|
60
|
+
Math.triplet?(4, 3, 5).should be_true
|
61
|
+
Math.triplet?(5, 4, 3).should be_false
|
62
|
+
Math.triplet?(0, 0, 0).should be_false
|
63
|
+
Math.triplet?(Math.sqrt(5), 2, 3).should be_false
|
64
|
+
Math.triplet?(1, 1, Math.sqrt(2)).should be_false
|
65
|
+
Math.triplet?(-1, -1, -1).should be_false
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'should calculate a series of Fibonacci numbers of a specified length' do
|
69
|
+
Math.fibs(-1).should == nil
|
70
|
+
Math.fibs(0).should == []
|
71
|
+
Math.fibs(1).should == [1]
|
72
|
+
Math.fibs(2).should == [1, 1]
|
73
|
+
Math.fibs(5).should == [1, 1, 2, 3, 5]
|
74
|
+
Math.fibs(10).should == [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Numeric do
|
4
|
+
|
5
|
+
it 'should get specific digits from a number' do
|
6
|
+
Math::PI.digits(0..-1).should == 3
|
7
|
+
12345.digits(0..2).should == 123
|
8
|
+
12345.digits(4).should == 5
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# Set up simplecov
|
2
|
+
require 'simplecov'
|
3
|
+
SimpleCov.start { add_filter '/spec/' }
|
4
|
+
|
5
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
6
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
7
|
+
require 'rspec'
|
8
|
+
require 'magician'
|
9
|
+
|
10
|
+
# Requires supporting files with custom matchers and macros, etc,
|
11
|
+
# in ./support/ and its subdirectories.
|
12
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
13
|
+
|
14
|
+
RSpec.configure do |config|
|
15
|
+
|
16
|
+
end
|
data/spec/string_spec.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe String do
|
4
|
+
|
5
|
+
it 'should determine if a string is a palindrome' do
|
6
|
+
''.palindrome?.should be_true
|
7
|
+
'a'.palindrome?.should be_true
|
8
|
+
'deed'.palindrome?.should be_true
|
9
|
+
'racecar'.palindrome?.should be_true
|
10
|
+
'cats'.palindrome?.should be_false
|
11
|
+
'no'.palindrome?.should be_false
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: magician
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Nicolas McCurdy
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-30 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 2.12.0
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 2.12.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: yard
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0.7'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0.7'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rdoc
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '3.12'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.12'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: bundler
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: jeweler
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 1.8.4
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 1.8.4
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: simplecov
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
description: A suite of handy methods for doing calculations in irb.
|
111
|
+
email: thenickperson@gmail.com
|
112
|
+
executables: []
|
113
|
+
extensions: []
|
114
|
+
extra_rdoc_files:
|
115
|
+
- LICENSE.txt
|
116
|
+
- README.md
|
117
|
+
files:
|
118
|
+
- .document
|
119
|
+
- .rspec
|
120
|
+
- .travis.yml
|
121
|
+
- Gemfile
|
122
|
+
- LICENSE.txt
|
123
|
+
- README.md
|
124
|
+
- Rakefile
|
125
|
+
- VERSION
|
126
|
+
- lib/magician.rb
|
127
|
+
- lib/magician/array.rb
|
128
|
+
- lib/magician/integer.rb
|
129
|
+
- lib/magician/math.rb
|
130
|
+
- lib/magician/numeric.rb
|
131
|
+
- lib/magician/shortcuts.rb
|
132
|
+
- lib/magician/string.rb
|
133
|
+
- spec/array_spec.rb
|
134
|
+
- spec/integer_spec.rb
|
135
|
+
- spec/math_spec.rb
|
136
|
+
- spec/numeric_spec.rb
|
137
|
+
- spec/shortcuts_spec.rb
|
138
|
+
- spec/spec_helper.rb
|
139
|
+
- spec/string_spec.rb
|
140
|
+
homepage: http://github.com/thenickperson/magician
|
141
|
+
licenses:
|
142
|
+
- MIT
|
143
|
+
post_install_message:
|
144
|
+
rdoc_options: []
|
145
|
+
require_paths:
|
146
|
+
- lib
|
147
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
148
|
+
none: false
|
149
|
+
requirements:
|
150
|
+
- - ! '>='
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
segments:
|
154
|
+
- 0
|
155
|
+
hash: 3387386332341206942
|
156
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
157
|
+
none: false
|
158
|
+
requirements:
|
159
|
+
- - ! '>='
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: '0'
|
162
|
+
requirements: []
|
163
|
+
rubyforge_project:
|
164
|
+
rubygems_version: 1.8.24
|
165
|
+
signing_key:
|
166
|
+
specification_version: 3
|
167
|
+
summary: A suite of handy methods for doing calculations in irb.
|
168
|
+
test_files: []
|