From 0912bacf8c5ac474a83bffc0408656b37d68ab32 Mon Sep 17 00:00:00 2001 From: NicklasXYZ Date: Sun, 5 Feb 2023 12:19:37 +0100 Subject: [PATCH] Add cartesian_product func --- src/gleam_community/maths/list.gleam | 28 +++++++++++++++++-- .../gleam_community_maths_list_test.gleam | 26 +++++++++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/src/gleam_community/maths/list.gleam b/src/gleam_community/maths/list.gleam index 40e7e75..c555b45 100644 --- a/src/gleam_community/maths/list.gleam +++ b/src/gleam_community/maths/list.gleam @@ -29,6 +29,8 @@ import gleam/list import gleam/int import gleam/float +import gleam/set +import gleam/io ///
/// @@ -146,7 +148,7 @@ pub fn permutation(arr: List(a)) -> List(a) { /// ///
/// -/// Generate a list containing all combinations of one element from each of two given lists. +/// Generate a list containing all combinations of pairs of elements coming from two given lists. /// ///
/// Example: @@ -165,6 +167,26 @@ pub fn permutation(arr: List(a)) -> List(a) { /// /// /// -pub fn cartesian_product(xarr: List(a), yarr: List(a)) -> List(a) { - todo +pub fn cartesian_product(xarr: List(a), yarr: List(a)) -> List(#(a, a)) { + let xset: set.Set(a) = + xarr + |> set.from_list() + let yset: set.Set(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)) { + io.debug(#(member0, member1)) + set.insert(accumulator1, #(member0, member1)) + }, + ) + }, + ) + |> set.to_list() } diff --git a/test/gleam/gleam_community_maths_list_test.gleam b/test/gleam/gleam_community_maths_list_test.gleam index 6ac7e9d..abd0b81 100644 --- a/test/gleam/gleam_community_maths_list_test.gleam +++ b/test/gleam/gleam_community_maths_list_test.gleam @@ -20,3 +20,29 @@ pub fn list_trim_test() { |> listx.trim(1, 4) |> should.equal(Ok([2.0, 3.0, 4.0, 5.0])) } + +pub fn list_cartesian_product_test() { + // An empty lists returns an empty list + [] + |> listx.cartesian_product([]) + |> should.equal([]) + + // Test with some arbitrary inputs + [1, 2, 3] + |> listx.cartesian_product([1, 2, 3]) + |> should.equal([ + #(1, 1), + #(1, 2), + #(1, 3), + #(2, 1), + #(2, 2), + #(2, 3), + #(3, 1), + #(3, 2), + #(3, 3), + ]) + + [1.0, 10.0] + |> listx.cartesian_product([1.0, 2.0]) + |> should.equal([#(1.0, 1.0), #(1.0, 2.0), #(10.0, 1.0), #(10.0, 2.0)]) +}