2023-11-19 22:40:59 +00:00
|
|
|
import gleam/list
|
2024-08-12 20:38:18 +00:00
|
|
|
import gleam/set
|
2024-12-07 22:46:49 +00:00
|
|
|
import gleam/yielder
|
|
|
|
import gleam_community/maths
|
2023-09-16 21:34:00 +00:00
|
|
|
import gleeunit/should
|
|
|
|
|
|
|
|
pub fn int_factorial_test() {
|
2024-08-16 22:44:21 +00:00
|
|
|
// Invalid input gives an error (factorial of negative number)
|
2024-12-07 22:46:49 +00:00
|
|
|
maths.factorial(-1)
|
2023-09-16 21:34:00 +00:00
|
|
|
|> should.be_error()
|
|
|
|
|
2024-08-16 22:44:21 +00:00
|
|
|
// Valid inputs for factorial of small numbers
|
2024-12-07 22:46:49 +00:00
|
|
|
maths.factorial(0)
|
2023-09-16 21:34:00 +00:00
|
|
|
|> should.equal(Ok(1))
|
|
|
|
|
2024-12-07 22:46:49 +00:00
|
|
|
maths.factorial(1)
|
2023-09-16 21:34:00 +00:00
|
|
|
|> should.equal(Ok(1))
|
|
|
|
|
2024-12-07 22:46:49 +00:00
|
|
|
maths.factorial(2)
|
2023-09-16 21:34:00 +00:00
|
|
|
|> should.equal(Ok(2))
|
|
|
|
|
2024-12-07 22:46:49 +00:00
|
|
|
maths.factorial(3)
|
2023-09-16 21:34:00 +00:00
|
|
|
|> should.equal(Ok(6))
|
|
|
|
|
2024-12-07 22:46:49 +00:00
|
|
|
maths.factorial(4)
|
2023-09-16 21:34:00 +00:00
|
|
|
|> should.equal(Ok(24))
|
|
|
|
}
|
|
|
|
|
2024-12-07 22:46:49 +00:00
|
|
|
pub fn int_combination_with_repetitions_test() {
|
2024-08-16 22:44:21 +00:00
|
|
|
// Invalid input: k < 0 should return an error
|
2024-12-07 22:46:49 +00:00
|
|
|
maths.combination_with_repetitions(1, -1)
|
2024-08-16 22:44:21 +00:00
|
|
|
|> should.be_error()
|
|
|
|
|
|
|
|
// Invalid input: n < 0 should return an error
|
2024-12-07 22:46:49 +00:00
|
|
|
maths.combination_with_repetitions(-1, 1)
|
2023-09-16 21:34:00 +00:00
|
|
|
|> should.be_error()
|
|
|
|
|
2024-08-16 22:44:21 +00:00
|
|
|
// Valid input: k > n with repetition allowed
|
2024-12-07 22:46:49 +00:00
|
|
|
maths.combination_with_repetitions(2, 3)
|
2024-08-16 22:44:21 +00:00
|
|
|
|> should.equal(Ok(4))
|
|
|
|
|
2024-12-07 22:46:49 +00:00
|
|
|
maths.combination_with_repetitions(4, 0)
|
2023-09-16 21:34:00 +00:00
|
|
|
|> should.equal(Ok(1))
|
|
|
|
|
2024-12-07 22:46:49 +00:00
|
|
|
// Valid input: k = n with repetition allows more combinations
|
|
|
|
maths.combination_with_repetitions(4, 4)
|
|
|
|
|> should.equal(Ok(35))
|
|
|
|
|
|
|
|
maths.combination_with_repetitions(4, 2)
|
|
|
|
|> should.equal(Ok(10))
|
|
|
|
|
|
|
|
maths.combination_with_repetitions(7, 5)
|
|
|
|
|> should.equal(Ok(462))
|
|
|
|
// NOTE: Tests with the 'combination' function that produce values that exceed
|
|
|
|
// precision of the JavaScript 'Number' primitive will result in errors
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn int_combination_without_repetitions_test() {
|
|
|
|
// Valid input: k > n without repetition gives 0 combinations
|
|
|
|
maths.combination(2, 3)
|
|
|
|
|> should.equal(Ok(0))
|
2024-08-16 22:44:21 +00:00
|
|
|
|
|
|
|
// Valid input: k = n without repetition gives 1 combination
|
2024-12-07 22:46:49 +00:00
|
|
|
maths.combination(4, 4)
|
2023-09-16 21:34:00 +00:00
|
|
|
|> should.equal(Ok(1))
|
|
|
|
|
2024-12-07 22:46:49 +00:00
|
|
|
// Valid input: zero combinations (k=0) should always yield 1 combination
|
|
|
|
maths.combination(4, 0)
|
|
|
|
|> should.equal(Ok(1))
|
2024-08-16 22:44:21 +00:00
|
|
|
|
|
|
|
// Valid input: k < n without and with repetition
|
2024-12-07 22:46:49 +00:00
|
|
|
maths.combination(4, 2)
|
2023-09-16 21:34:00 +00:00
|
|
|
|> should.equal(Ok(6))
|
|
|
|
|
2024-08-16 22:44:21 +00:00
|
|
|
// Valid input with larger values of n and k
|
2024-12-07 22:46:49 +00:00
|
|
|
maths.combination(7, 5)
|
2023-09-16 21:34:00 +00:00
|
|
|
|> should.equal(Ok(21))
|
2024-12-07 22:46:49 +00:00
|
|
|
}
|
2024-08-16 22:44:21 +00:00
|
|
|
|
2024-12-07 22:46:49 +00:00
|
|
|
pub fn math_permutation_with_repetitions_test() {
|
|
|
|
// Invalid input: k < 0 should return an error
|
|
|
|
maths.permutation_with_repetitions(1, -1)
|
|
|
|
|> should.be_error()
|
|
|
|
|
|
|
|
// Valid input: k > n with repetition allowed gives non-zero permutations
|
|
|
|
maths.permutation_with_repetitions(2, 3)
|
|
|
|
|> should.equal(Ok(8))
|
|
|
|
|
|
|
|
maths.permutation_with_repetitions(4, 0)
|
|
|
|
|> should.equal(Ok(1))
|
|
|
|
|
|
|
|
// Valid input: k = n permutations with repetition
|
|
|
|
maths.permutation_with_repetitions(4, 4)
|
|
|
|
|> should.equal(Ok(256))
|
|
|
|
|
|
|
|
maths.permutation_with_repetitions(4, 2)
|
|
|
|
|> should.equal(Ok(16))
|
|
|
|
|
|
|
|
maths.permutation_with_repetitions(6, 2)
|
|
|
|
|> should.equal(Ok(36))
|
|
|
|
|
|
|
|
maths.permutation_with_repetitions(6, 3)
|
|
|
|
|> should.equal(Ok(216))
|
2023-09-16 21:34:00 +00:00
|
|
|
}
|
|
|
|
|
2024-12-07 22:46:49 +00:00
|
|
|
pub fn math_permutation_without_repetitions_test() {
|
2024-08-16 22:44:21 +00:00
|
|
|
// Invalid input: k < 0 should return an error
|
2024-12-07 22:46:49 +00:00
|
|
|
maths.permutation(1, -1)
|
2023-09-16 21:34:00 +00:00
|
|
|
|> should.be_error()
|
|
|
|
|
2024-08-16 22:44:21 +00:00
|
|
|
// Invalid input: n < 0 should return an error
|
2024-12-07 22:46:49 +00:00
|
|
|
maths.permutation(-1, 1)
|
2024-08-16 22:44:21 +00:00
|
|
|
|> should.be_error()
|
|
|
|
|
|
|
|
// Valid input: k > n without repetition gives 0 permutations
|
2024-12-07 22:46:49 +00:00
|
|
|
maths.permutation(2, 3)
|
2024-08-16 22:44:21 +00:00
|
|
|
|> should.equal(Ok(0))
|
|
|
|
|
|
|
|
// Valid input: k = 0 should always yield 1 permutation
|
2024-12-07 22:46:49 +00:00
|
|
|
maths.permutation(4, 0)
|
2024-08-16 22:44:21 +00:00
|
|
|
|> should.equal(Ok(1))
|
|
|
|
|
|
|
|
// Valid input: k = n permutations without repetition
|
2024-12-07 22:46:49 +00:00
|
|
|
maths.permutation(4, 4)
|
2024-08-15 22:15:58 +00:00
|
|
|
|> should.equal(Ok(24))
|
2023-09-16 21:34:00 +00:00
|
|
|
|
2024-08-16 22:44:21 +00:00
|
|
|
// Valid input: k < n permutations without and with repetition
|
2024-12-07 22:46:49 +00:00
|
|
|
maths.permutation(4, 2)
|
2023-09-16 21:34:00 +00:00
|
|
|
|> should.equal(Ok(12))
|
2024-08-15 22:15:58 +00:00
|
|
|
|
2024-08-16 22:44:21 +00:00
|
|
|
// Valid input with larger values of n and k
|
2024-12-07 22:46:49 +00:00
|
|
|
maths.permutation(6, 2)
|
2024-08-15 22:15:58 +00:00
|
|
|
|> should.equal(Ok(30))
|
|
|
|
|
2024-12-07 22:46:49 +00:00
|
|
|
maths.permutation(6, 3)
|
2024-08-15 22:15:58 +00:00
|
|
|
|> should.equal(Ok(120))
|
2023-09-16 21:34:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn list_cartesian_product_test() {
|
2024-08-16 22:44:21 +00:00
|
|
|
// An empty list returns an empty list as the Cartesian product
|
|
|
|
let xset = set.from_list([])
|
|
|
|
let yset = set.from_list([])
|
|
|
|
let expected_result = set.from_list([])
|
|
|
|
xset
|
2024-12-07 22:46:49 +00:00
|
|
|
|> maths.cartesian_product(yset)
|
2024-08-16 22:44:21 +00:00
|
|
|
|> should.equal(expected_result)
|
|
|
|
|
|
|
|
// Cartesian product of two sets with the same elements
|
|
|
|
let xset = set.from_list([1, 2, 3])
|
|
|
|
let yset = set.from_list([1, 2, 3])
|
|
|
|
let expected_result =
|
2023-12-19 10:10:36 +00:00
|
|
|
set.from_list([
|
|
|
|
#(1, 1),
|
|
|
|
#(1, 2),
|
|
|
|
#(1, 3),
|
|
|
|
#(2, 1),
|
|
|
|
#(2, 2),
|
|
|
|
#(2, 3),
|
|
|
|
#(3, 1),
|
|
|
|
#(3, 2),
|
|
|
|
#(3, 3),
|
2024-08-16 22:44:21 +00:00
|
|
|
])
|
|
|
|
xset
|
2024-12-07 22:46:49 +00:00
|
|
|
|> maths.cartesian_product(yset)
|
2024-08-16 22:44:21 +00:00
|
|
|
|> should.equal(expected_result)
|
|
|
|
|
|
|
|
// Cartesian product with floating-point numbers
|
|
|
|
let xset = set.from_list([1.0, 10.0])
|
|
|
|
let yset = set.from_list([1.0, 2.0])
|
|
|
|
let expected_result =
|
|
|
|
set.from_list([#(1.0, 1.0), #(1.0, 2.0), #(10.0, 1.0), #(10.0, 2.0)])
|
|
|
|
xset
|
2024-12-07 22:46:49 +00:00
|
|
|
|> maths.cartesian_product(yset)
|
2024-08-16 22:44:21 +00:00
|
|
|
|> should.equal(expected_result)
|
|
|
|
|
|
|
|
// Cartesian product of sets with different sizes
|
|
|
|
let xset = set.from_list([1.0, 10.0, 100.0])
|
|
|
|
let yset = set.from_list([1.0, 2.0])
|
|
|
|
let expected_result =
|
|
|
|
set.from_list([
|
|
|
|
#(1.0, 1.0),
|
|
|
|
#(1.0, 2.0),
|
|
|
|
#(10.0, 1.0),
|
|
|
|
#(10.0, 2.0),
|
|
|
|
#(100.0, 1.0),
|
|
|
|
#(100.0, 2.0),
|
|
|
|
])
|
|
|
|
xset
|
2024-12-07 22:46:49 +00:00
|
|
|
|> maths.cartesian_product(yset)
|
2024-08-16 22:44:21 +00:00
|
|
|
|> should.equal(expected_result)
|
|
|
|
|
|
|
|
// Cartesian product with different types (strings)
|
|
|
|
let xset = set.from_list(["a", "y", "z"])
|
|
|
|
let yset = set.from_list(["a", "x"])
|
|
|
|
let expected_result =
|
|
|
|
set.from_list([
|
|
|
|
#("a", "a"),
|
|
|
|
#("a", "x"),
|
|
|
|
#("y", "a"),
|
|
|
|
#("y", "x"),
|
|
|
|
#("z", "a"),
|
|
|
|
#("z", "x"),
|
|
|
|
])
|
|
|
|
xset
|
2024-12-07 22:46:49 +00:00
|
|
|
|> maths.cartesian_product(yset)
|
2024-08-16 22:44:21 +00:00
|
|
|
|> should.equal(expected_result)
|
|
|
|
}
|
|
|
|
|
2024-12-07 22:46:49 +00:00
|
|
|
pub fn cartesian_product_mixed_types_test() {
|
|
|
|
// Cartesian product of two empty sets
|
|
|
|
set.from_list([])
|
|
|
|
|> maths.cartesian_product(set.from_list([]))
|
|
|
|
|> should.equal(set.from_list([]))
|
2024-08-16 22:44:21 +00:00
|
|
|
|
2024-12-07 22:46:49 +00:00
|
|
|
// Cartesian product of two sets with numeric values
|
|
|
|
set.from_list([1.0, 10.0])
|
|
|
|
|> maths.cartesian_product(set.from_list([1.0, 2.0]))
|
|
|
|
|> should.equal(
|
|
|
|
set.from_list([#(1.0, 1.0), #(1.0, 2.0), #(10.0, 1.0), #(10.0, 2.0)]),
|
|
|
|
)
|
|
|
|
|
|
|
|
// Cartesian product of two sets with different types
|
|
|
|
set.from_list(["1", "10"])
|
|
|
|
|> maths.cartesian_product(set.from_list([1.0, 2.0]))
|
|
|
|
|> should.equal(
|
|
|
|
set.from_list([#("1", 1.0), #("1", 2.0), #("10", 1.0), #("10", 2.0)]),
|
2024-08-16 22:44:21 +00:00
|
|
|
)
|
2024-12-07 22:46:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn list_permutation_with_repetitions_test() {
|
|
|
|
// Invalid input: k < 0 should return an error for an empty list
|
|
|
|
[]
|
|
|
|
|> maths.list_permutation_with_repetitions(-1)
|
2024-08-16 22:44:21 +00:00
|
|
|
|> should.be_error()
|
|
|
|
|
|
|
|
// Valid input: An empty list returns a single empty permutation
|
|
|
|
let assert Ok(permutations) =
|
|
|
|
[]
|
2024-12-07 22:46:49 +00:00
|
|
|
|> maths.list_permutation_with_repetitions(0)
|
2024-08-16 22:44:21 +00:00
|
|
|
permutations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
2024-08-16 22:44:21 +00:00
|
|
|
|> should.equal([[]])
|
|
|
|
|
|
|
|
let assert Ok(permutations) =
|
|
|
|
["a"]
|
2024-12-07 22:46:49 +00:00
|
|
|
|> maths.list_permutation_with_repetitions(1)
|
2024-08-16 22:44:21 +00:00
|
|
|
permutations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
2024-08-16 22:44:21 +00:00
|
|
|
|> should.equal([["a"]])
|
|
|
|
|
|
|
|
// 4-permutations of a single element repeats it 4 times
|
|
|
|
let assert Ok(permutations) =
|
|
|
|
["a"]
|
2024-12-07 22:46:49 +00:00
|
|
|
|> maths.list_permutation_with_repetitions(4)
|
2024-08-16 22:44:21 +00:00
|
|
|
permutations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
2024-08-16 22:44:21 +00:00
|
|
|
|> should.equal([["a", "a", "a", "a"]])
|
|
|
|
|
2024-12-07 22:46:49 +00:00
|
|
|
// 2-permutations of [1, 2] with repetition
|
2024-08-16 22:44:21 +00:00
|
|
|
let assert Ok(permutations) =
|
|
|
|
[1, 2]
|
2024-12-07 22:46:49 +00:00
|
|
|
|> maths.list_permutation_with_repetitions(2)
|
2024-08-16 22:44:21 +00:00
|
|
|
permutations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
2024-08-16 22:44:21 +00:00
|
|
|
|> set.from_list()
|
2024-12-07 22:46:49 +00:00
|
|
|
|> should.equal(set.from_list([[1, 1], [1, 2], [2, 2], [2, 1]]))
|
|
|
|
|
|
|
|
// 3-permutations of [1, 2, 3] with repetition
|
|
|
|
let assert Ok(permutations) =
|
|
|
|
[1, 2, 3]
|
|
|
|
|> maths.list_permutation_with_repetitions(3)
|
|
|
|
permutations
|
|
|
|
|> yielder.to_list()
|
|
|
|
|> should.equal([
|
|
|
|
[1, 1, 1],
|
|
|
|
[1, 1, 2],
|
|
|
|
[1, 1, 3],
|
|
|
|
[1, 2, 1],
|
|
|
|
[1, 2, 2],
|
|
|
|
[1, 2, 3],
|
|
|
|
[1, 3, 1],
|
|
|
|
[1, 3, 2],
|
|
|
|
[1, 3, 3],
|
|
|
|
[2, 1, 1],
|
|
|
|
[2, 1, 2],
|
|
|
|
[2, 1, 3],
|
|
|
|
[2, 2, 1],
|
|
|
|
[2, 2, 2],
|
|
|
|
[2, 2, 3],
|
|
|
|
[2, 3, 1],
|
|
|
|
[2, 3, 2],
|
|
|
|
[2, 3, 3],
|
|
|
|
[3, 1, 1],
|
|
|
|
[3, 1, 2],
|
|
|
|
[3, 1, 3],
|
|
|
|
[3, 2, 1],
|
|
|
|
[3, 2, 2],
|
|
|
|
[3, 2, 3],
|
|
|
|
[3, 3, 1],
|
|
|
|
[3, 3, 2],
|
|
|
|
[3, 3, 3],
|
|
|
|
])
|
|
|
|
|
|
|
|
// Repeated elements allow more possibilities when repetition is allowed
|
|
|
|
let assert Ok(permutations) =
|
|
|
|
[1.0, 1.0]
|
|
|
|
|> maths.list_permutation_with_repetitions(2)
|
|
|
|
permutations
|
|
|
|
|> yielder.to_list()
|
|
|
|
|> should.equal([[1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0]])
|
2024-08-16 22:44:21 +00:00
|
|
|
|
2024-12-07 22:46:49 +00:00
|
|
|
let assert Ok(permutations) =
|
|
|
|
["a", "b", "c", "d", "e"]
|
|
|
|
|> maths.list_permutation_with_repetitions(5)
|
|
|
|
permutations
|
|
|
|
|> yielder.to_list()
|
|
|
|
|> list.length()
|
|
|
|
|> should.equal(3125)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn list_permutation_without_repetitions_test() {
|
|
|
|
// Invalid input: k > n should return an error without repetition
|
|
|
|
[1, 2]
|
|
|
|
|> maths.list_permutation(3)
|
|
|
|
|> should.be_error()
|
|
|
|
|
|
|
|
// Singleton list returns a single permutation regardless of repetition settings
|
|
|
|
let assert Ok(permutations) =
|
|
|
|
["a"]
|
|
|
|
|> maths.list_permutation(1)
|
|
|
|
permutations
|
|
|
|
|> yielder.to_list()
|
|
|
|
|> should.equal([["a"]])
|
|
|
|
|
|
|
|
// 2-permutations of [1, 2] without repetition
|
2024-08-16 22:44:21 +00:00
|
|
|
let assert Ok(permutations) =
|
|
|
|
[1, 2]
|
2024-12-07 22:46:49 +00:00
|
|
|
|> maths.list_permutation(2)
|
2024-08-16 22:44:21 +00:00
|
|
|
permutations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
|
|
|
|> should.equal([[1, 2], [2, 1]])
|
|
|
|
|
|
|
|
// 2-permutations without repetition
|
|
|
|
let assert Ok(result) =
|
|
|
|
[1, 2, 3]
|
|
|
|
|> maths.list_permutation(2)
|
|
|
|
result
|
|
|
|
|> yielder.to_list()
|
|
|
|
|> should.equal([[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]])
|
2024-08-16 22:44:21 +00:00
|
|
|
|
|
|
|
// 3-permutations of [1, 2, 3] without repetition
|
|
|
|
let assert Ok(permutations) =
|
|
|
|
[1, 2, 3]
|
2024-12-07 22:46:49 +00:00
|
|
|
|> maths.list_permutation(3)
|
2024-08-16 22:44:21 +00:00
|
|
|
permutations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
|
|
|
|> should.equal([
|
|
|
|
[1, 2, 3],
|
|
|
|
[1, 3, 2],
|
|
|
|
[2, 1, 3],
|
|
|
|
[2, 3, 1],
|
|
|
|
[3, 1, 2],
|
|
|
|
[3, 2, 1],
|
|
|
|
])
|
|
|
|
|
|
|
|
// 3-permutations of [1, 2, 3, 4] without repetition
|
2024-08-16 22:44:21 +00:00
|
|
|
let assert Ok(permutations) =
|
2024-12-07 22:46:49 +00:00
|
|
|
[1, 2, 3, 4]
|
|
|
|
|> maths.list_permutation(3)
|
2024-08-16 22:44:21 +00:00
|
|
|
permutations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
|
|
|
|> should.equal([
|
|
|
|
[1, 2, 3],
|
|
|
|
[1, 2, 4],
|
|
|
|
[1, 3, 2],
|
|
|
|
[1, 3, 4],
|
|
|
|
[1, 4, 2],
|
|
|
|
[1, 4, 3],
|
|
|
|
[2, 1, 3],
|
|
|
|
[2, 1, 4],
|
|
|
|
[2, 3, 1],
|
|
|
|
[2, 3, 4],
|
|
|
|
[2, 4, 1],
|
|
|
|
[2, 4, 3],
|
|
|
|
[3, 1, 2],
|
|
|
|
[3, 1, 4],
|
|
|
|
[3, 2, 1],
|
|
|
|
[3, 2, 4],
|
|
|
|
[3, 4, 1],
|
|
|
|
[3, 4, 2],
|
|
|
|
[4, 1, 2],
|
|
|
|
[4, 1, 3],
|
|
|
|
[4, 2, 1],
|
|
|
|
[4, 2, 3],
|
|
|
|
[4, 3, 1],
|
|
|
|
[4, 3, 2],
|
|
|
|
])
|
2024-08-16 22:44:21 +00:00
|
|
|
|
|
|
|
// Repeated elements are treated as distinct in permutations without repetition
|
|
|
|
let assert Ok(permutations) =
|
|
|
|
[1.0, 1.0]
|
2024-12-07 22:46:49 +00:00
|
|
|
|> maths.list_permutation(2)
|
2024-08-16 22:44:21 +00:00
|
|
|
permutations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
2024-08-16 22:44:21 +00:00
|
|
|
|> should.equal([[1.0, 1.0], [1.0, 1.0]])
|
|
|
|
|
|
|
|
// Large inputs: Ensure the correct number of permutations is generated
|
|
|
|
let assert Ok(permutations) =
|
|
|
|
["a", "b", "c", "d", "e"]
|
2024-12-07 22:46:49 +00:00
|
|
|
|> maths.list_permutation(5)
|
2024-08-16 22:44:21 +00:00
|
|
|
permutations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
2024-08-16 22:44:21 +00:00
|
|
|
|> list.length()
|
|
|
|
|> should.equal(120)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn permutation_alignment_test() {
|
|
|
|
// Test: Number of generated permutations should match the expected count
|
|
|
|
// Without repetitions
|
|
|
|
let arr = ["a", "b", "c", "d", "e", "f"]
|
|
|
|
let length = list.length(arr)
|
|
|
|
|
2024-12-07 22:46:49 +00:00
|
|
|
let assert Ok(number_of_permutations) = maths.permutation(length, length)
|
2024-08-16 22:44:21 +00:00
|
|
|
let assert Ok(permutations) =
|
|
|
|
arr
|
2024-12-07 22:46:49 +00:00
|
|
|
|> maths.list_permutation(length)
|
2024-08-16 22:44:21 +00:00
|
|
|
permutations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
2024-08-16 22:44:21 +00:00
|
|
|
|> list.length()
|
|
|
|
|> should.equal(number_of_permutations)
|
|
|
|
|
|
|
|
// With repetitions
|
|
|
|
let arr = ["a", "b", "c", "d", "e", "f"]
|
|
|
|
let length = list.length(arr)
|
|
|
|
|
|
|
|
let assert Ok(number_of_permutations) =
|
2024-12-07 22:46:49 +00:00
|
|
|
maths.permutation_with_repetitions(length, length)
|
2024-08-16 22:44:21 +00:00
|
|
|
let assert Ok(permutations) =
|
|
|
|
arr
|
2024-12-07 22:46:49 +00:00
|
|
|
|> maths.list_permutation_with_repetitions(length)
|
2024-08-16 22:44:21 +00:00
|
|
|
permutations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
2024-08-16 22:44:21 +00:00
|
|
|
|> list.length()
|
|
|
|
|> should.equal(number_of_permutations)
|
|
|
|
}
|
|
|
|
|
2024-12-07 22:46:49 +00:00
|
|
|
pub fn list_combination_with_repetitions_test() {
|
2024-08-16 22:44:21 +00:00
|
|
|
// Invalid input: k < 0 should return an error for an empty list
|
|
|
|
[]
|
2024-12-07 22:46:49 +00:00
|
|
|
|> maths.list_combination_with_repetitions(-1)
|
2024-08-16 22:44:21 +00:00
|
|
|
|> should.be_error()
|
|
|
|
|
|
|
|
// Valid input: k > n with repetition allowed
|
|
|
|
let assert Ok(combinations) =
|
|
|
|
[1, 2]
|
2024-12-07 22:46:49 +00:00
|
|
|
|> maths.list_combination_with_repetitions(3)
|
2024-08-16 22:44:21 +00:00
|
|
|
combinations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
2024-08-16 22:44:21 +00:00
|
|
|
|> should.equal([[1, 1, 1], [1, 1, 2], [1, 2, 2], [2, 2, 2]])
|
|
|
|
|
|
|
|
let assert Ok(combinations) =
|
|
|
|
[]
|
2024-12-07 22:46:49 +00:00
|
|
|
|> maths.list_combination_with_repetitions(0)
|
2024-08-16 22:44:21 +00:00
|
|
|
combinations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
2024-08-16 22:44:21 +00:00
|
|
|
|> should.equal([[]])
|
|
|
|
|
|
|
|
let assert Ok(combinations) =
|
2024-12-07 22:46:49 +00:00
|
|
|
[1, 2]
|
|
|
|
|> maths.list_combination_with_repetitions(1)
|
2024-08-16 22:44:21 +00:00
|
|
|
combinations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
|
|
|
|> should.equal([[1], [2]])
|
2024-08-16 22:44:21 +00:00
|
|
|
|
|
|
|
let assert Ok(combinations) =
|
|
|
|
[1, 2]
|
2024-12-07 22:46:49 +00:00
|
|
|
|> maths.list_combination_with_repetitions(2)
|
2024-08-16 22:44:21 +00:00
|
|
|
combinations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
|
|
|
|> should.equal([[1, 1], [1, 2], [2, 2]])
|
2024-08-16 22:44:21 +00:00
|
|
|
|
|
|
|
let assert Ok(combinations) =
|
2024-12-07 22:46:49 +00:00
|
|
|
[1, 2, 3, 4]
|
|
|
|
|> maths.list_combination_with_repetitions(2)
|
2024-08-16 22:44:21 +00:00
|
|
|
combinations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
|
|
|
|> should.equal([
|
|
|
|
[1, 1],
|
|
|
|
[1, 2],
|
|
|
|
[1, 3],
|
|
|
|
[1, 4],
|
|
|
|
[2, 2],
|
|
|
|
[2, 3],
|
|
|
|
[2, 4],
|
|
|
|
[3, 3],
|
|
|
|
[3, 4],
|
|
|
|
[4, 4],
|
|
|
|
])
|
2024-08-16 22:44:21 +00:00
|
|
|
|
2024-12-07 22:46:49 +00:00
|
|
|
// 3-combination of [1, 2, 3] with repetition
|
2024-08-16 22:44:21 +00:00
|
|
|
let assert Ok(combinations) =
|
2024-12-07 22:46:49 +00:00
|
|
|
[1, 2, 3]
|
|
|
|
|> maths.list_combination_with_repetitions(3)
|
2024-08-16 22:44:21 +00:00
|
|
|
combinations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
|
|
|
|> should.equal([
|
|
|
|
[1, 1, 1],
|
|
|
|
[1, 1, 2],
|
|
|
|
[1, 1, 3],
|
|
|
|
[1, 2, 2],
|
|
|
|
[1, 2, 3],
|
|
|
|
[1, 3, 3],
|
|
|
|
[2, 2, 2],
|
|
|
|
[2, 2, 3],
|
|
|
|
[2, 3, 3],
|
|
|
|
[3, 3, 3],
|
|
|
|
])
|
|
|
|
|
|
|
|
// 3-permutations of [1, 2, 3, 4] with repetition
|
|
|
|
let assert Ok(permutations) =
|
|
|
|
maths.list_combination_with_repetitions([1, 2, 3, 4], 3)
|
2024-08-16 22:44:21 +00:00
|
|
|
|
2024-12-07 22:46:49 +00:00
|
|
|
permutations
|
|
|
|
|> yielder.to_list()
|
|
|
|
|> should.equal([
|
|
|
|
[1, 1, 1],
|
|
|
|
[1, 1, 2],
|
|
|
|
[1, 1, 3],
|
|
|
|
[1, 1, 4],
|
|
|
|
[1, 2, 2],
|
|
|
|
[1, 2, 3],
|
|
|
|
[1, 2, 4],
|
|
|
|
[1, 3, 3],
|
|
|
|
[1, 3, 4],
|
|
|
|
[1, 4, 4],
|
|
|
|
[2, 2, 2],
|
|
|
|
[2, 2, 3],
|
|
|
|
[2, 2, 4],
|
|
|
|
[2, 3, 3],
|
|
|
|
[2, 3, 4],
|
|
|
|
[2, 4, 4],
|
|
|
|
[3, 3, 3],
|
|
|
|
[3, 3, 4],
|
|
|
|
[3, 4, 4],
|
|
|
|
[4, 4, 4],
|
|
|
|
])
|
|
|
|
|
|
|
|
// Repetition creates more possibilities even with identical elements
|
2024-08-16 22:44:21 +00:00
|
|
|
let assert Ok(combinations) =
|
2024-12-07 22:46:49 +00:00
|
|
|
[1.0, 1.0]
|
|
|
|
|> maths.list_combination_with_repetitions(2)
|
2024-08-16 22:44:21 +00:00
|
|
|
combinations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
|
|
|
|> should.equal([[1.0, 1.0], [1.0, 1.0], [1.0, 1.0]])
|
2024-08-16 22:44:21 +00:00
|
|
|
|
|
|
|
let assert Ok(combinations) =
|
2024-12-07 22:46:49 +00:00
|
|
|
["a", "b", "c", "d", "e"]
|
|
|
|
|> maths.list_combination_with_repetitions(5)
|
2024-08-16 22:44:21 +00:00
|
|
|
combinations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
|
|
|
|> list.length()
|
|
|
|
|> should.equal(126)
|
|
|
|
}
|
2024-08-16 22:44:21 +00:00
|
|
|
|
2024-12-07 22:46:49 +00:00
|
|
|
pub fn list_combination_without_repetitions_test() {
|
|
|
|
// Invalid input: k > n should return an error without repetition
|
|
|
|
[1, 2]
|
|
|
|
|> maths.list_combination(3)
|
|
|
|
|> should.be_error()
|
|
|
|
|
|
|
|
// Valid input: Empty list should return a single empty combination
|
2024-08-16 22:44:21 +00:00
|
|
|
let assert Ok(combinations) =
|
2024-12-07 22:46:49 +00:00
|
|
|
[]
|
|
|
|
|> maths.list_combination(0)
|
2024-08-16 22:44:21 +00:00
|
|
|
combinations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
|
|
|
|> should.equal([[]])
|
2023-09-16 21:34:00 +00:00
|
|
|
|
2024-12-07 22:46:49 +00:00
|
|
|
// 1-combination of [1, 2] without and with repetition
|
2024-08-16 22:44:21 +00:00
|
|
|
let assert Ok(combinations) =
|
2024-12-07 22:46:49 +00:00
|
|
|
[1, 2]
|
|
|
|
|> maths.list_combination(1)
|
2024-08-16 22:44:21 +00:00
|
|
|
combinations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
|
|
|
|> should.equal([[1], [2]])
|
2024-08-16 22:44:21 +00:00
|
|
|
|
2024-12-07 22:46:49 +00:00
|
|
|
// 2-combination of [1, 2] without and with repetition
|
2024-08-16 22:44:21 +00:00
|
|
|
let assert Ok(combinations) =
|
2024-12-07 22:46:49 +00:00
|
|
|
[1, 2]
|
|
|
|
|> maths.list_combination(2)
|
2024-08-16 22:44:21 +00:00
|
|
|
combinations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
|
|
|
|> should.equal([[1, 2]])
|
2024-08-16 22:44:21 +00:00
|
|
|
|
2024-12-07 22:46:49 +00:00
|
|
|
// 2-combination of [1, 2, 3, 4] without and with repetition
|
2024-08-16 22:44:21 +00:00
|
|
|
let assert Ok(combinations) =
|
2024-12-07 22:46:49 +00:00
|
|
|
[1, 2, 3, 4]
|
|
|
|
|> maths.list_combination(2)
|
2024-08-16 22:44:21 +00:00
|
|
|
combinations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
|
|
|
|> should.equal([[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]])
|
2024-08-16 22:44:21 +00:00
|
|
|
|
2024-12-07 22:46:49 +00:00
|
|
|
// 3-combination of [1, 2, 3, 4] without repetition
|
2024-08-16 22:44:21 +00:00
|
|
|
let assert Ok(combinations) =
|
2024-12-07 22:46:49 +00:00
|
|
|
[1, 2, 3, 4]
|
|
|
|
|> maths.list_combination(3)
|
2024-08-16 22:44:21 +00:00
|
|
|
combinations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
|
|
|
|> should.equal([[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]])
|
2024-08-16 22:44:21 +00:00
|
|
|
|
2024-12-07 22:46:49 +00:00
|
|
|
// Combinations treat repeated elements as distinct in certain scenarios
|
2024-08-16 22:44:21 +00:00
|
|
|
let assert Ok(combinations) =
|
2024-12-07 22:46:49 +00:00
|
|
|
[1.0, 1.0]
|
|
|
|
|> maths.list_combination(2)
|
2024-08-16 22:44:21 +00:00
|
|
|
combinations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
|
|
|
|> should.equal([[1.0, 1.0]])
|
2024-08-16 22:44:21 +00:00
|
|
|
|
2024-12-07 22:46:49 +00:00
|
|
|
// Large input: Ensure correct number of combinations is generated
|
2024-08-16 22:44:21 +00:00
|
|
|
let assert Ok(combinations) =
|
|
|
|
["a", "b", "c", "d", "e"]
|
2024-12-07 22:46:49 +00:00
|
|
|
|> maths.list_combination(5)
|
2024-08-16 22:44:21 +00:00
|
|
|
combinations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
2024-08-16 22:44:21 +00:00
|
|
|
|> list.length()
|
2024-12-07 22:46:49 +00:00
|
|
|
|> should.equal(1)
|
2024-08-16 22:44:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn combination_alignment_test() {
|
|
|
|
// Test: Number of generated combinations should match the expected count
|
|
|
|
// Without repetitions
|
|
|
|
let arr = ["a", "b", "c", "d", "e", "f"]
|
|
|
|
let length = list.length(arr)
|
|
|
|
|
2024-12-07 22:46:49 +00:00
|
|
|
let assert Ok(number_of_combinations) = maths.combination(length, length)
|
2024-08-16 22:44:21 +00:00
|
|
|
let assert Ok(combinations) =
|
|
|
|
arr
|
2024-12-07 22:46:49 +00:00
|
|
|
|> maths.list_combination(length)
|
2024-08-16 22:44:21 +00:00
|
|
|
combinations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
2024-08-16 22:44:21 +00:00
|
|
|
|> list.length()
|
|
|
|
|> should.equal(number_of_combinations)
|
|
|
|
|
|
|
|
// With repetitions
|
|
|
|
let arr = ["a", "b", "c", "d", "e", "f"]
|
|
|
|
let length = list.length(arr)
|
|
|
|
|
|
|
|
let assert Ok(number_of_combinations) =
|
2024-12-07 22:46:49 +00:00
|
|
|
maths.combination_with_repetitions(length, length)
|
2024-08-16 22:44:21 +00:00
|
|
|
let assert Ok(combinations) =
|
|
|
|
arr
|
2024-12-07 22:46:49 +00:00
|
|
|
|> maths.list_combination_with_repetitions(length)
|
2024-08-16 22:44:21 +00:00
|
|
|
combinations
|
2024-12-07 22:46:49 +00:00
|
|
|
|> yielder.to_list()
|
2024-08-16 22:44:21 +00:00
|
|
|
|> list.length()
|
|
|
|
|> should.equal(number_of_combinations)
|
|
|
|
}
|