mirror of
https://github.com/TheAlgorithms/Ruby
synced 2024-12-28 22:24:14 +01:00
Merge pull request #76 from snood1205/add-maths-algos
Add absolute value, aliquot sum, ceil, and square root
This commit is contained in:
commit
e4c33632a4
9 changed files with 153 additions and 0 deletions
|
@ -24,6 +24,12 @@
|
|||
* [Euclidean Gcd](https://github.com/TheAlgorithms/Ruby/blob/master/discrete_mathematics/euclidean_gcd.rb)
|
||||
* [Lcm](https://github.com/TheAlgorithms/Ruby/blob/master/discrete_mathematics/lcm.rb)
|
||||
|
||||
## Maths
|
||||
* [Absolute Value](https://github.com/TheAlgorithms/Ruby/blob/master/maths/abs.rb)
|
||||
* [Aliquot Sum](https://github.com/TheAlgorithms/Ruby/blob/master/maths/aliquot.rb)
|
||||
* [Ceil](https://github.com/TheAlgorithms/Ruby/blob/master/maths/ceil.rb)
|
||||
* [Square Root](https://github.com/TheAlgorithms/Ruby/blob/master/maths/square_root.rb)
|
||||
|
||||
## Other
|
||||
* [Fisher Yates](https://github.com/TheAlgorithms/Ruby/blob/master/other/fisher_yates.rb)
|
||||
|
||||
|
|
10
maths/abs.rb
Normal file
10
maths/abs.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Calculates the absolute value of a number
|
||||
class Abs
|
||||
def self.call(number)
|
||||
return -number if number.negative?
|
||||
|
||||
number
|
||||
end
|
||||
end
|
18
maths/abs_test.rb
Normal file
18
maths/abs_test.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'minitest/autorun'
|
||||
require_relative './abs'
|
||||
|
||||
class AbsTest < Minitest::Test
|
||||
def test_positive_number
|
||||
assert_equal Abs.call(4), 4
|
||||
end
|
||||
|
||||
def test_zero
|
||||
assert_equal Abs.call(0), 0
|
||||
end
|
||||
|
||||
def test_negative_number
|
||||
assert_equal Abs.call(-9), 9
|
||||
end
|
||||
end
|
21
maths/aliquot_sum.rb
Normal file
21
maths/aliquot_sum.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative './square_root'
|
||||
require_relative './ceil'
|
||||
|
||||
# Calculates the aliquot sum of a number (the sum of all proper divisors of a number)
|
||||
class AliquotSum
|
||||
class << self
|
||||
def call(number)
|
||||
divisors(number).sum
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def divisors(number)
|
||||
low_divisors = (1..Ceil.call(SquareRoot.call(number))).select { |num| (number % num).zero? }
|
||||
high_divisors = low_divisors.map { |div| number / div }
|
||||
(low_divisors + high_divisors).uniq - [number]
|
||||
end
|
||||
end
|
||||
end
|
21
maths/aliquot_sum_test.rb
Normal file
21
maths/aliquot_sum_test.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'minitest/autorun'
|
||||
require_relative './aliquot_sum'
|
||||
|
||||
class AliquotSumTest < Minitest::Test
|
||||
def test_zero
|
||||
assert_equal AliquotSum.call(0), 0
|
||||
end
|
||||
|
||||
def test_one
|
||||
assert_equal Abs.call(1), 1
|
||||
end
|
||||
|
||||
def test_many
|
||||
(2..100).each do |number|
|
||||
expected_aliquot_sum = (1...number).select { |num| (number % num).zero? }.sum
|
||||
assert_equal AliquotSum.call(number), expected_aliquot_sum
|
||||
end
|
||||
end
|
||||
end
|
11
maths/ceil.rb
Normal file
11
maths/ceil.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Ceil
|
||||
class << self
|
||||
def call(number)
|
||||
return number if number.is_a?(Integer) || number == number.to_i
|
||||
|
||||
number.to_i + 1
|
||||
end
|
||||
end
|
||||
end
|
18
maths/ceil_test.rb
Normal file
18
maths/ceil_test.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'minitest/autorun'
|
||||
require_relative './ceil'
|
||||
|
||||
class CeilTest < Minitest::Test
|
||||
def test_integer
|
||||
assert_equal Ceil.call(4), 4
|
||||
end
|
||||
|
||||
def test_float_at_integer
|
||||
assert_equal Ceil.call(4.0), 4
|
||||
end
|
||||
|
||||
def test_float_not_at_integer
|
||||
assert_equal Ceil.call(4.01), 5
|
||||
end
|
||||
end
|
26
maths/square_root.rb
Normal file
26
maths/square_root.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Calculates the square root of a number
|
||||
class SquareRoot
|
||||
class << self
|
||||
EPSILON = 1E-10
|
||||
|
||||
def call(number)
|
||||
raise DomainError, 'Cannot find square root of negative number' if number.negative?
|
||||
return 0 if number.zero?
|
||||
|
||||
find_root(number)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_root(x0, xn = x0)
|
||||
xn1 = xn - ((xn * xn - x0) / (2.0 * xn))
|
||||
return xn1 if (xn1 - xn).abs <= EPSILON
|
||||
|
||||
find_root(x0, xn1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class DomainError < StandardError; end
|
22
maths/square_root_test.rb
Normal file
22
maths/square_root_test.rb
Normal file
|
@ -0,0 +1,22 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'minitest/autorun'
|
||||
require_relative './square_root'
|
||||
|
||||
class SquareRootTest < Minitest::Test
|
||||
def test_negative_number
|
||||
assert_raises DomainError do
|
||||
SquareRoot.call(-1)
|
||||
end
|
||||
end
|
||||
|
||||
def test_zero
|
||||
assert_equal 0, SquareRoot.call(0)
|
||||
end
|
||||
|
||||
def test_all_numbers_below_1024
|
||||
(1...1024).each do |num|
|
||||
assert_in_delta SquareRoot.call(num), Math.sqrt(num), 1E-12
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue