mirror of
https://github.com/sigmasternchen/gleam-community-maths
synced 2025-03-15 07:59:01 +00:00
Add extra tests. Improve Euclidean modulo description.
This commit is contained in:
parent
0c01501272
commit
cbcee32f22
9 changed files with 75 additions and 43 deletions
|
@ -4,7 +4,7 @@ version = "1.0.2"
|
|||
licences = ["Apache-2.0"]
|
||||
description = "A basic maths library"
|
||||
repository = { type = "github", user = "gleam-community", repo = "maths" }
|
||||
gleam = ">= 0.33.0"
|
||||
gleam = ">= 0.32.0"
|
||||
|
||||
[dependencies]
|
||||
gleam_stdlib = "~> 0.34"
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
# You typically do not need to edit this file
|
||||
|
||||
packages = [
|
||||
{ name = "gleam_stdlib", version = "0.34.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "1FB8454D2991E9B4C0C804544D8A9AD0F6184725E20D63C3155F0AEB4230B016" },
|
||||
{ name = "gleeunit", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "4E75DCF846D653848094169304743DFFB386E3AECCCF611F99ADB735FF4D4DD9" },
|
||||
{ name = "gleam_stdlib", version = "0.36.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "C0D14D807FEC6F8A08A7C9EF8DFDE6AE5C10E40E21325B2B29365965D82EB3D4" },
|
||||
{ name = "gleeunit", version = "1.0.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "D364C87AFEB26BDB4FB8A5ABDE67D635DC9FA52D6AB68416044C35B096C6882D" },
|
||||
]
|
||||
|
||||
[requirements]
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
//// * [`lcm`](#lcm)
|
||||
//// * [`divisors`](#divisors)
|
||||
//// * [`proper_divisors`](#proper_divisors)
|
||||
//// * [`int_euclidean_modulo`](#int_euclidean_modulo)
|
||||
//// * **Sums and products**
|
||||
//// * [`float_sum`](#float_sum)
|
||||
//// * [`int_sum`](#int_sum)
|
||||
|
@ -102,15 +103,23 @@ fn do_gcd(x: Int, y: Int) -> Int {
|
|||
/// </a>
|
||||
/// </div>
|
||||
///
|
||||
/// The function calculates the Euclidian modulo of two numbers
|
||||
/// The Euclidian_modulo is the modulo that most often is used in maths
|
||||
/// rather than the normal truncating modulo operation that is used most
|
||||
/// often in programming through the % operator
|
||||
/// In contrast to the % operator this function will always return a positive
|
||||
/// result
|
||||
///
|
||||
/// Given two integers, $$x$$ (dividend) and $$y$$ (divisor), the Euclidean modulo of $$x$$ by $$y$$,
|
||||
/// denoted as $$x \mod y$$, is the remainder $$r$$ of the division of $$x$$ by $$y$$, such that:
|
||||
///
|
||||
/// \\[
|
||||
/// x = q \cdot y + r \quad \text{and} \quad 0 \leq r < |y|,
|
||||
/// \\]
|
||||
///
|
||||
/// where $$q$$ is an integer that represents the quotient of the division.
|
||||
///
|
||||
/// Like the gleam division operator / this will return 0 if one of the
|
||||
/// parameters are 0 as this is not defined in mathematics
|
||||
/// The Euclidean modulo function of two numbers, is the remainder operation most commonly utilized in
|
||||
/// mathematics. This differs from the standard truncating modulo operation frequently employed in
|
||||
/// programming via the `%` operator. Unlike the `%` operator, which may return negative results
|
||||
/// depending on the divisor's sign, the Euclidean modulo function is designed to
|
||||
/// always yield a positive outcome, ensuring consistency with mathematical conventions.
|
||||
///
|
||||
/// Note that like the Gleam division operator `/` this will return `0` if one of the arguments is `0`.
|
||||
///
|
||||
///
|
||||
/// <details>
|
||||
|
@ -120,13 +129,13 @@ fn do_gcd(x: Int, y: Int) -> Int {
|
|||
/// import gleam_community/maths/arithmetics
|
||||
///
|
||||
/// pub fn example() {
|
||||
/// arithmetics.euclidian_modulo(15, 4)
|
||||
/// arithmetics.euclidean_modulo(15, 4)
|
||||
/// |> should.equal(3)
|
||||
///
|
||||
/// arithmetics.euclidian_modulo(-3, -2)
|
||||
/// arithmetics.euclidean_modulo(-3, -2)
|
||||
/// |> should.equal(1)
|
||||
///
|
||||
/// arithmetics.euclidian_modulo(5, 0)
|
||||
/// arithmetics.euclidean_modulo(5, 0)
|
||||
/// |> should.equal(0)
|
||||
/// }
|
||||
/// </details>
|
||||
|
@ -137,7 +146,7 @@ fn do_gcd(x: Int, y: Int) -> Int {
|
|||
/// </a>
|
||||
/// </div>
|
||||
///
|
||||
pub fn euclidian_modulo(x: Int, y: Int) -> Int {
|
||||
pub fn int_euclidean_modulo(x: Int, y: Int) -> Int {
|
||||
case x % y, x, y {
|
||||
_, 0, _ -> 0
|
||||
_, _, 0 -> 0
|
||||
|
|
|
@ -239,8 +239,7 @@ pub fn permutation(n: Int, k: Int) -> Result(Int, String) {
|
|||
False -> {
|
||||
let assert Ok(v1) = factorial(n)
|
||||
let assert Ok(v2) = factorial(n - k)
|
||||
v1
|
||||
/ v2
|
||||
v1 / v2
|
||||
|> Ok
|
||||
}
|
||||
}
|
||||
|
@ -416,14 +415,17 @@ pub fn cartesian_product(xarr: List(a), yarr: List(a)) -> List(#(a, a)) {
|
|||
yarr
|
||||
|> set.from_list()
|
||||
xset
|
||||
|> set.fold(set.new(), fn(accumulator0: set.Set(#(a, a)), member0: a) -> set.Set(
|
||||
#(a, a),
|
||||
) {
|
||||
set.fold(yset, accumulator0, fn(accumulator1: set.Set(#(a, a)), member1: a) -> set.Set(
|
||||
#(a, a),
|
||||
) {
|
||||
set.insert(accumulator1, #(member0, member1))
|
||||
})
|
||||
})
|
||||
|> set.fold(
|
||||
set.new(),
|
||||
fn(accumulator0: set.Set(#(a, a)), member0: a) -> set.Set(#(a, a)) {
|
||||
set.fold(
|
||||
yset,
|
||||
accumulator0,
|
||||
fn(accumulator1: set.Set(#(a, a)), member1: a) -> set.Set(#(a, a)) {
|
||||
set.insert(accumulator1, #(member0, member1))
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
|> set.to_list()
|
||||
}
|
||||
|
|
|
@ -819,8 +819,7 @@ pub fn logarithm(x: Float, base: option.Option(Float)) -> Result(Float, String)
|
|||
// Apply the "change of base formula"
|
||||
let assert Ok(numerator) = logarithm_10(x)
|
||||
let assert Ok(denominator) = logarithm_10(a)
|
||||
numerator
|
||||
/. denominator
|
||||
numerator /. denominator
|
||||
|> Ok
|
||||
}
|
||||
False ->
|
||||
|
|
|
@ -445,8 +445,7 @@ fn round_ties_up(p: Float, x: Float) -> Float {
|
|||
let remainder: Float = xabs -. xabs_truncated
|
||||
case remainder {
|
||||
_ if remainder >=. 0.5 && x >=. 0.0 ->
|
||||
float_sign(x) *. truncate_float(xabs +. 1.0)
|
||||
/. p
|
||||
float_sign(x) *. truncate_float(xabs +. 1.0) /. p
|
||||
_ -> float_sign(x) *. xabs_truncated /. p
|
||||
}
|
||||
}
|
||||
|
@ -577,8 +576,7 @@ pub fn int_absolute_value(x: Int) -> Int {
|
|||
/// </div>
|
||||
///
|
||||
pub fn float_absolute_difference(a: Float, b: Float) -> Float {
|
||||
a
|
||||
-. b
|
||||
a -. b
|
||||
|> float_absolute_value()
|
||||
}
|
||||
|
||||
|
@ -618,8 +616,7 @@ pub fn float_absolute_difference(a: Float, b: Float) -> Float {
|
|||
/// </div>
|
||||
///
|
||||
pub fn int_absolute_difference(a: Int, b: Int) -> Int {
|
||||
a
|
||||
- b
|
||||
a - b
|
||||
|> int_absolute_value()
|
||||
}
|
||||
|
||||
|
|
|
@ -98,8 +98,7 @@ fn float_absolute_value(x: Float) -> Float {
|
|||
}
|
||||
|
||||
fn float_absolute_difference(a: Float, b: Float) -> Float {
|
||||
a
|
||||
-. b
|
||||
a -. b
|
||||
|> float_absolute_value()
|
||||
}
|
||||
|
||||
|
|
|
@ -21,14 +21,31 @@ pub fn int_gcd_test() {
|
|||
|> should.equal(6)
|
||||
}
|
||||
|
||||
pub fn euclidian_modulo_test() {
|
||||
arithmetics.euclidian_modulo(15, 4)
|
||||
pub fn int_euclidean_modulo_test() {
|
||||
// Base Case: Positive x, Positive y
|
||||
// Note that the truncated, floored, and euclidean
|
||||
// definitions should agree for this base case
|
||||
arithmetics.int_euclidean_modulo(15, 4)
|
||||
|> should.equal(3)
|
||||
|
||||
arithmetics.euclidian_modulo(-3, -2)
|
||||
// Case: Positive x, Negative y
|
||||
arithmetics.int_euclidean_modulo(15, -4)
|
||||
|> should.equal(3)
|
||||
|
||||
// Case: Negative x, Positive y
|
||||
arithmetics.int_euclidean_modulo(-15, 4)
|
||||
|> should.equal(1)
|
||||
|
||||
arithmetics.euclidian_modulo(5, 0)
|
||||
// Case: Negative x, Negative y
|
||||
arithmetics.int_euclidean_modulo(-15, -4)
|
||||
|> should.equal(1)
|
||||
|
||||
// Case: Positive x, Zero y
|
||||
arithmetics.int_euclidean_modulo(5, 0)
|
||||
|> should.equal(0)
|
||||
|
||||
// Case: Zero x, Negative y
|
||||
arithmetics.int_euclidean_modulo(0, 5)
|
||||
|> should.equal(0)
|
||||
}
|
||||
|
||||
|
|
|
@ -311,17 +311,26 @@ pub fn math_round_ties_away_test() {
|
|||
|> should.equal(Ok(12.0))
|
||||
|
||||
// Round 1. digit BEFORE decimal point
|
||||
piecewise.round(12.0654, option.Some(-1), option.Some(piecewise.RoundTiesAway),
|
||||
piecewise.round(
|
||||
12.0654,
|
||||
option.Some(-1),
|
||||
option.Some(piecewise.RoundTiesAway),
|
||||
)
|
||||
|> should.equal(Ok(10.0))
|
||||
|
||||
// Round 2. digit BEFORE decimal point
|
||||
piecewise.round(12.0654, option.Some(-2), option.Some(piecewise.RoundTiesAway),
|
||||
piecewise.round(
|
||||
12.0654,
|
||||
option.Some(-2),
|
||||
option.Some(piecewise.RoundTiesAway),
|
||||
)
|
||||
|> should.equal(Ok(0.0))
|
||||
|
||||
// Round 2. digit BEFORE decimal point
|
||||
piecewise.round(12.0654, option.Some(-3), option.Some(piecewise.RoundTiesAway),
|
||||
piecewise.round(
|
||||
12.0654,
|
||||
option.Some(-3),
|
||||
option.Some(piecewise.RoundTiesAway),
|
||||
)
|
||||
|> should.equal(Ok(0.0))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue