Cartesian product of two or more lists: Difference between revisions

m
Automated syntax highlighting fixup (second round - minor fixes)
m (syntax highlighting fixup automation)
m (Automated syntax highlighting fixup (second round - minor fixes))
Line 21:
 
<br>
 
=={{header|11l}}==
{{trans|Go}}
<syntaxhighlight lang="11l">F cart_prod(a, b)
V p = [(0, 0)] * (a.len * b.len)
V i = 0
Line 38 ⟶ 37:
print(cart_prod(empty_array, [1, 2]))</syntaxhighlight>
====Alternative version====
<syntaxhighlight lang="11l">F cart_prod(a, b)
R multiloop(a, b, (aa, bb) -> (aa, bb))</syntaxhighlight>
{{out}}
Line 47 ⟶ 46:
[]
</pre>
 
=={{header|Action!}}==
<syntaxhighlight lang=Action"action!">DEFINE MAX_COUNT="10"
DEFINE MAX_RESULT="100"
 
Line 170 ⟶ 168:
[1,2,3]x[]x[500,100]=[]
</pre>
 
=={{header|Ada}}==
<syntaxhighlight lang=Ada"ada">with Ada.Text_IO; use Ada.Text_Io;
with Ada.Containers.Doubly_Linked_Lists;
with Ada.Strings.Fixed;
Line 284 ⟶ 281:
{(1,30,500),(1,30,100),(2,30,500),(2,30,100),(3,30,500),(3,30,100)}
{}</pre>
 
=={{header|APL}}==
 
Line 293 ⟶ 289:
a matrix, and the task is asking for a list, you also need to ravel the result.
 
<syntaxhighlight lang=APL"apl">cart ← ,∘.,</syntaxhighlight>
 
{{out}}
Line 310 ⟶ 306:
list of lists.
 
<syntaxhighlight lang=APL"apl">nary_cart ← ⊃(,∘.,)/</syntaxhighlight>
 
{{out}}
Line 351 ⟶ 347:
↑nary_cart(1 2 3)(⍬)(50 100) ⍝ empty output
</pre>
 
=={{header|AppleScript}}==
<syntaxhighlight lang=AppleScript"applescript">-- CARTESIAN PRODUCTS ---------------------------------------------------------
 
-- Two lists:
Line 547 ⟶ 542:
 
[]</pre>
 
=={{header|Arturo}}==
{{trans|Ruby}}
<syntaxhighlight lang="rebol">loop [
[[1 2][3 4]]
[[3 4][1 2]]
Line 571 ⟶ 565:
[[1 30 500] [1 30 100] [2 30 500] [2 30 100] [3 30 500] [3 30 100]]
[]</pre>
 
=={{header|AutoHotkey}}==
<syntaxhighlight lang=AutoHotkey"autohotkey">example := [
(join,
[[1, 2], [3, 4]]
Line 636 ⟶ 629:
[]</pre>
=={{header|Bracmat}}==
<syntaxhighlight lang=Bracmat"bracmat">( ( mul
= R a b A B
. :?R
Line 703 ⟶ 696:
(.3 30 100)
.</pre>
 
=={{header|C}}==
Recursive implementation for computing the Cartesian product of lists. In the pursuit of making it as interactive as possible, the parsing function ended up taking the most space. The product set expression must be supplied enclosed by double quotes. Prints out usage on incorrect invocation.
<syntaxhighlight lang=C"c">
#include<string.h>
#include<stdlib.h>
Line 848 ⟶ 840:
{}
</pre>
 
=={{header|C sharp|C#}}==
<syntaxhighlight lang="csharp">using System;
public class Program
{
Line 904 ⟶ 895:
{}</pre>
If the number of lists is known, LINQ provides an easier solution:
<syntaxhighlight lang="csharp">public static void Main()
{
///...
Line 925 ⟶ 916:
{(1, 30, 500), (1, 30, 100), (2, 30, 500), (2, 30, 100), (3, 30, 500), (3, 30, 100)}
</pre>
 
=={{header|C++}}==
<syntaxhighlight lang="cpp">
#include <iostream>
#include <vector>
Line 993 ⟶ 983:
{ (1 30 500) (1 30 100) (2 30 500) (2 30 100) (3 30 500) (3 30 100) }
{ }</pre>
 
=={{header|Clojure}}==
<syntaxhighlight lang=Clojure"clojure">
(ns clojure.examples.product
(:gen-class)
Line 1,009 ⟶ 998:
</syntaxhighlight>
'''Output'''
<syntaxhighlight lang="clojure">
(doseq [lst [ [[1,2],[3,4]],
[[3,4],[1,2]], [[], [1, 2]],
Line 1,061 ⟶ 1,050:
()
</pre>
 
=={{header|Common Lisp}}==
<syntaxhighlight lang="lisp">(defun cartesian-product (s1 s2)
"Compute the cartesian product of two sets represented as lists"
(loop for x in s1
Line 1,071 ⟶ 1,059:
'''Output'''
 
<syntaxhighlight lang="lisp">
CL-USER> (cartesian-product '(1 2) '(3 4))
((1 3) (1 4) (2 3) (2 4))
Line 1,084 ⟶ 1,072:
'''Extra credit:'''
 
<syntaxhighlight lang="lisp">(defun n-cartesian-product (l)
"Compute the n-cartesian product of a list of sets (each of them represented as list).
Algorithm:
Line 1,098 ⟶ 1,086:
'''Output:'''
 
<syntaxhighlight lang="lisp">CL-USER> (n-cartesian-product '((1776 1789) (7 12) (4 14 23) (0 1)))
((1776 7 4 0) (1776 7 4 1) (1776 7 14 0) (1776 7 14 1) (1776 7 23 0) (1776 7 23 1) (1776 12 4 0) (1776 12 4 1) (1776 12 14 0) (1776 12 14 1) (1776 12 23 0) (1776 12 23 1) (1789 7 4 0) (1789 7 4 1) (1789 7 14 0) (1789 7 14 1) (1789 7 23 0) (1789 7 23 1) (1789 12 4 0) (1789 12 4 1) (1789 12 14 0) (1789 12 14 1) (1789 12 23 0) (1789 12 23 1))
CL-USER> (n-cartesian-product '((1 2 3) (30) (500 100)))
Line 1,105 ⟶ 1,093:
NIL
</syntaxhighlight>
 
=={{header|Crystal}}==
The first function is the basic task. The version overloaded for one argument is the extra credit task, implemented using recursion.
<syntaxhighlight lang="crystal">def cartesian_product(a, b)
return a.flat_map { |i| b.map { |j| [i, j] } }
end
Line 1,165 ⟶ 1,152:
[[1776, 7, 4, 0], [1776, 7, 4, 1], [1776, 7, 14, 0], [1776, 7, 14, 1], [1776, 7, 23, 0], [1776, 7, 23, 1], [1776, 12, 4, 0], [1776, 12, 4, 1], [1776, 12, 14, 0], [1776, 12, 14, 1], [1776, 12, 23, 0], [1776, 12, 23, 1], [1789, 7, 4, 0], [1789, 7, 4, 1], [1789, 7, 14, 0], [1789, 7, 14, 1], [1789, 7, 23, 0], [1789, 7, 23, 1], [1789, 12, 4, 0], [1789, 12, 4, 1], [1789, 12, 14, 0], [1789, 12, 14, 1], [1789, 12, 23, 0], [1789, 12, 23, 1]]
</pre>
 
=={{header|D}}==
<syntaxhighlight lang=D"d">import std.stdio;
 
void main() {
Line 1,215 ⟶ 1,201:
{{libheader| System.SysUtils}}
{{Trans|Go}}
<syntaxhighlight lang=Delphi"delphi">
program Cartesian_product_of_two_or_more_lists;
 
Line 1,362 ⟶ 1,348:
 
[]</pre>
 
=={{header|F Sharp|F#}}==
===The Task===
<syntaxhighlight lang="fsharp">
//Nigel Galloway February 12th., 2018
let cP2 n g = List.map (fun (n,g)->[n;g]) (List.allPairs n g)
Line 1,378 ⟶ 1,363:
 
===Extra Credit===
<syntaxhighlight lang="fsharp">
//Nigel Galloway August 14th., 2018
let cP ng=Seq.foldBack(fun n g->[for n' in n do for g' in g do yield n'::g']) ng [[]]
Line 1,397 ⟶ 1,382:
cP [[1;2;3];[];[500;100]] -> []
</pre>
 
=={{header|Factor}}==
<syntaxhighlight lang=Factor"factor">IN: scratchpad { 1 2 } { 3 4 } cartesian-product .
{ { { 1 3 } { 1 4 } } { { 2 3 } { 2 4 } } }
IN: scratchpad { 3 4 } { 1 2 } cartesian-product .
Line 1,407 ⟶ 1,391:
IN: scratchpad { } { 1 2 } cartesian-product .
{ }</syntaxhighlight>
 
=={{header|FreeBASIC}}==
I'll leave the extra credit part for someone else. It's just going to amount to repeatedly finding Cartesian products and [[Flatten a list|flattening]] the result, so considerably less interesting than Cartesian products where the list items themselves can be lists.
 
<syntaxhighlight lang=freebasic>#define MAXLEN 64
 
type listitem ' An item of a list may be a number
is_num as boolean ' or another list, so I have to account
union ' for both, implemented as a union.
list as any ptr ' FreeBASIC is twitchy about circularly
num as uinteger ' defined types, so one workaround is to
end union ' use a generic pointer that I will cast
end type ' later.
 
type list
length as uinteger 'simple, fixed storage length lists
item(1 to MAXLEN) as listitem 'are good enough for this example
end type
 
sub print_list( list as list )
print "{";
if list.length = 0 then print "}"; : return
for i as uinteger = 1 to list.length
if list.item(i).is_num then
print str(list.item(i).num);
else 'recursively print sublist
print_list( *cast(list ptr, list.item(i).list) )
end if
if i<list.length then print ", "; else print "}"; 'handle comma
next i 'gracefully
return
end sub
 
function cartprod( A as list, B as list ) as list
dim as uinteger i, j
dim as list C
dim as list ptr inner 'for brevity
C.length = 0
for i = 1 to A.length
for j = 1 to B.length
C.length += 1
C.item(C.length).is_num = false 'each item of the new list is a list itself
inner = allocate( sizeof(list) ) 'make space for it
C.item(C.length).list = inner
inner->length = 2 'each inner list contains two items
inner->item(1) = A.item(i) 'one from the first list
inner->item(2) = B.item(j) 'and one from the second
next j
next i
return C
end function
 
dim as list EMPTY, A, B, R
EMPTY.length = 0
A.length = 2
A.item(1).is_num = true : A.item(1).num = 1
A.item(2).is_num = true : A.item(2).num = 2
B.length = 2
B.item(1).is_num = true : B.item(1).num = 3
B.item(2).is_num = true : B.item(2).num = 4
 
R = cartprod(A, B)
print_list(R) : print 'print_list does not supply a final newline
R = cartprod(B, A) : print_list(R) : print
R = cartprod(A, EMPTY) : print_list(R) : print
R = cartprod(EMPTY, A) : print_list(R) : print</syntaxhighlight>
{{out}}<pre>{{1, 3}, {1, 4}, {2, 3}, {2, 4}}
{{3, 1}, {3, 2}, {4, 1}, {4, 2}}
{}
{}
</pre>
 
=={{header|Fortran}}==
This implementation is hard to extend to n-ary products but it is simple and works well for binary products of lists of any length.
 
<syntaxhighlight lang="fortran">
! Created by simon on 29/04/2021.
Line 1,589 ⟶ 1,501:
 
<!--
=={{header|FreeBASIC}}==
I'll leave the extra credit part for someone else. It's just going to amount to repeatedly finding Cartesian products and [[Flatten a list|flattening]] the result, so considerably less interesting than Cartesian products where the list items themselves can be lists.
 
<syntaxhighlight lang="freebasic">#define MAXLEN 64
 
type listitem ' An item of a list may be a number
is_num as boolean ' or another list, so I have to account
union ' for both, implemented as a union.
list as any ptr ' FreeBASIC is twitchy about circularly
num as uinteger ' defined types, so one workaround is to
end union ' use a generic pointer that I will cast
end type ' later.
 
type list
length as uinteger 'simple, fixed storage length lists
item(1 to MAXLEN) as listitem 'are good enough for this example
end type
 
sub print_list( list as list )
print "{";
if list.length = 0 then print "}"; : return
for i as uinteger = 1 to list.length
if list.item(i).is_num then
print str(list.item(i).num);
else 'recursively print sublist
print_list( *cast(list ptr, list.item(i).list) )
end if
if i<list.length then print ", "; else print "}"; 'handle comma
next i 'gracefully
return
end sub
 
function cartprod( A as list, B as list ) as list
dim as uinteger i, j
dim as list C
dim as list ptr inner 'for brevity
C.length = 0
for i = 1 to A.length
for j = 1 to B.length
C.length += 1
C.item(C.length).is_num = false 'each item of the new list is a list itself
inner = allocate( sizeof(list) ) 'make space for it
C.item(C.length).list = inner
inner->length = 2 'each inner list contains two items
inner->item(1) = A.item(i) 'one from the first list
inner->item(2) = B.item(j) 'and one from the second
next j
next i
return C
end function
 
dim as list EMPTY, A, B, R
EMPTY.length = 0
A.length = 2
A.item(1).is_num = true : A.item(1).num = 1
A.item(2).is_num = true : A.item(2).num = 2
B.length = 2
B.item(1).is_num = true : B.item(1).num = 3
B.item(2).is_num = true : B.item(2).num = 4
 
R = cartprod(A, B)
print_list(R) : print 'print_list does not supply a final newline
R = cartprod(B, A) : print_list(R) : print
R = cartprod(A, EMPTY) : print_list(R) : print
R = cartprod(EMPTY, A) : print_list(R) : print</syntaxhighlight>
{{out}}<pre>{{1, 3}, {1, 4}, {2, 3}, {2, 4}}
{{3, 1}, {3, 2}, {4, 1}, {4, 2}}
{}
{}
</pre>
=={{header|Fōrmulæ}}==
 
Line 1,597 ⟶ 1,579:
The option to show Fōrmulæ programs and their results is showing images. Unfortunately images cannot be uploaded in Rosetta Code.
-->
 
=={{header|Go}}==
'''Basic Task'''
<syntaxhighlight lang="go">package main
 
import "fmt"
Line 1,634 ⟶ 1,615:
 
This solution minimizes allocations and computes and fills the result sequentially.
<syntaxhighlight lang="go">package main
 
import "fmt"
Line 1,735 ⟶ 1,716:
 
Code here is more compact, but with the cost of more garbage produced. It produces the same result as cartN above.
<syntaxhighlight lang="go">func cartN(a ...[]int) (c [][]int) {
if len(a) == 0 {
return [][]int{nil}
Line 1,750 ⟶ 1,731:
 
This is a compact recursive version like Extra credit 2 but the result list is ordered differently. This is still a correct result if you consider a cartesian product to be a set, which is an unordered collection. Note that the set elements are still ordered lists. A cartesian product is an unordered collection of ordered collections. It draws attention though to the gloss of using list representations as sets. Any of the functions here will accept duplicate elements in the input lists, and then produce duplicate elements in the result.
<syntaxhighlight lang="go">func cartN(a ...[]int) (c [][]int) {
if len(a) == 0 {
return [][]int{nil}
Line 1,763 ⟶ 1,744:
return
}</syntaxhighlight>
 
=={{header|Groovy}}==
'''Solution:'''<br>
The following ''CartesianCategory'' class allows for modification of regular ''Iterable'' interface behavior, overloading ''Iterable'''s ''multiply'' (*) operator to perform a Cartesian Product when the second operand is also an ''Iterable''.
<syntaxhighlight lang="groovy">class CartesianCategory {
static Iterable multiply(Iterable a, Iterable b) {
assert [a,b].every { it != null }
Line 1,776 ⟶ 1,756:
'''Test:'''<br>
The ''mixin'' method call is necessary to make the multiply (*) operator work.
<syntaxhighlight lang="groovy">Iterable.metaClass.mixin CartesianCategory
 
println "\nCore Solution:"
Line 1,833 ⟶ 1,813:
[Ringo, Palmer, Garfunkle],
]</pre>
 
=={{header|Haskell}}==
Various routes can be taken to Cartesian products in Haskell.
For the product of two lists we could write:
<syntaxhighlight lang=Haskell"haskell">cartProd :: [a] -> [b] -> [(a, b)]
cartProd xs ys =
[ (x, y)
Line 1,844 ⟶ 1,823:
 
more directly:
<syntaxhighlight lang=Haskell"haskell">cartProd :: [a] -> [b] -> [(a, b)]
cartProd xs ys = xs >>= \x -> ys >>= \y -> [(x, y)]</syntaxhighlight>
 
applicatively:
<syntaxhighlight lang=Haskell"haskell">cartProd :: [a] -> [b] -> [(a, b)]
cartProd xs ys = (,) <$> xs <*> ys</syntaxhighlight>
 
parsimoniously:
<syntaxhighlight lang=Haskell"haskell">cartProd :: [a] -> [b] -> [(a, b)]
cartProd = (<*>) . fmap (,)</syntaxhighlight>
 
We might test any of these with:
<syntaxhighlight lang="haskell">main :: IO ()
main =
mapM_ print $
Line 1,869 ⟶ 1,848:
 
For the n-ary Cartesian product of an arbitrary number of lists, we could apply the Prelude's standard '''sequence''' function to a list of lists,
<syntaxhighlight lang="haskell">cartProdN :: [[a]] -> [[a]]
cartProdN = sequence
 
Line 1,878 ⟶ 1,857:
 
or we could define ourselves an equivalent function over a list of lists in terms of a fold, for example as:
<syntaxhighlight lang="haskell">cartProdN :: [[a]] -> [[a]]
cartProdN = foldr (\xs as -> xs >>= (<$> as) . (:)) [[]]</syntaxhighlight>
or, equivalently, as:
<syntaxhighlight lang="haskell">cartProdN :: [[a]] -> [[a]]
cartProdN = foldr
(\xs as ->
Line 1,889 ⟶ 1,868:
[[]]</syntaxhighlight>
testing any of these with something like:
<syntaxhighlight lang="haskell">main :: IO ()
main = do
mapM_ print $
Line 1,926 ⟶ 1,905:
 
[]</pre>
 
=={{header|J}}==
The J primitive [http://code.jsoftware.com/wiki/Vocabulary/curlylf catalogue] <code>{</code> forms the Cartesian Product of two or more boxed lists. The result is a multi-dimensional array (which can be reshaped to a simple list of lists if desired).
<syntaxhighlight lang="j"> { 1776 1789 ; 7 12 ; 4 14 23 ; 0 1 NB. result is 4 dimensional array with shape 2 2 3 2
┌────────────┬────────────┐
│1776 7 4 0 │1776 7 4 1 │
Line 1,972 ⟶ 1,950:
{ 1 2 3 ; '' ; 50 100 NB. result is an empty 3-dimensional array with shape 3 0 2
</syntaxhighlight>
 
=={{header|Java}}==
{{works with|Java Virtual Machine|1.8}}
<syntaxhighlight lang=Java"java">
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
Line 2,007 ⟶ 1,984:
 
'''Using a generic class with a recursive function'''
<syntaxhighlight lang=Java"java">
import java.util.ArrayList;
import java.util.Arrays;
Line 2,064 ⟶ 2,041:
}
</syntaxhighlight>
 
=={{header|JavaScript}}==
===ES6===
Line 2,071 ⟶ 2,047:
 
For the Cartesian product of just two lists:
<syntaxhighlight lang=JavaScript"javascript">(() => {
// CARTESIAN PRODUCT OF TWO LISTS ---------------------
 
Line 2,095 ⟶ 2,071:
 
Abstracting a little more, we can define the cartesian product quite economically in terms of a general applicative operator:
<syntaxhighlight lang=Javascript"javascript">(() => {
 
// CARTESIAN PRODUCT OF TWO LISTS ---------------------
Line 2,141 ⟶ 2,117:
 
For the n-ary Cartesian product over a list of lists:
<syntaxhighlight lang=JavaScript"javascript">(() => {
const main = () => {
// n-ary Cartesian product of a list of lists.
Line 2,235 ⟶ 2,211:
Imperative implementations of Cartesian products are inevitably less compact and direct, but we can certainly write an iterative translation of a fold over nested applications of '''bind''' or '''concatMap''':
 
<syntaxhighlight lang=JavaScript"javascript">(() => {
// n-ary Cartesian product of a list of lists
// ( Imperative implementation )
Line 2,346 ⟶ 2,322:
 
[]</pre>
 
=={{header|jq}}==
 
jq is stream-oriented and so we begin by defining a function that will emit a stream of the elements of the Cartesian product of two arrays:
<syntaxhighlight lang="jq">
def products: .[0][] as $x | .[1][] as $y | [$x,$y];
</syntaxhighlight>
 
To generate an array of these arrays, one would in practice most likely simply write `[products]`, but to comply with the requirements of this article, we can define `product` as:
<syntaxhighlight lang="jq">
def product: [products];
</syntaxhighlight>
Line 2,372 ⟶ 2,347:
 
And
<syntaxhighlight lang="jq">
[[1,2], []] | product
</syntaxhighlight>
Line 2,383 ⟶ 2,358:
Given an array of two or more arrays as input, `cartesians` as defined here produces a stream of the components of their Cartesian product:
 
<syntaxhighlight lang="jq">
def cartesians:
if length <= 2 then products
Line 2,402 ⟶ 2,377:
[[1, 2, 3], [], [500, 100] ] | [cartesians] | length
# 0
 
=={{header|Julia}}==
Run in REPL.
<syntaxhighlight lang="julia">
# Product {1, 2} × {3, 4}
collect(Iterators.product([1, 2], [3, 4]))
Line 2,423 ⟶ 2,397:
collect(Iterators.product([1, 2, 3], [], [500, 100]))
</syntaxhighlight>
 
=={{header|Kotlin}}==
<syntaxhighlight lang="scala">// version 1.1.2
 
fun flattenList(nestList: List<Any>): List<Any> {
Line 2,540 ⟶ 2,513:
]
</pre>
 
=={{header|langur}}==
We could use mapX() to map each set of values to a function, but this assignment only requires an array of arrays, so we use the X() function.
 
{{works with|langur|0.8.3}}
<syntaxhighlight lang="langur">writeln X([1, 2], [3, 4]) == [[1, 3], [1, 4], [2, 3], [2, 4]]
writeln X([3, 4], [1, 2]) == [[3, 1], [3, 2], [4, 1], [4, 2]]
writeln X([1, 2], []) == []
Line 2,572 ⟶ 2,544:
[]
</pre>
 
=={{header|Lua}}==
=== Functional ===
An iterator is created to output the product items.
<syntaxhighlight lang="lua"> local pk,upk = table.pack, table.unpack
local getn = function(t)return #t end
local const = function(k)return function(e) return k end end
Line 2,641 ⟶ 2,612:
 
It is possible that specialising descend by depth may yield a further improvement in performance, but it would only be able to eliminate the lookup of ''sets[depth]'' and the if test, because the reference to ''result[depth]'' is required; I doubt the increase in complexity would be worth the (potential) improvement in performance.
<syntaxhighlight lang="lua">local function cartesian_product(sets)
local result = {}
local set_count = #sets
Line 2,693 ⟶ 2,664:
=== Imperative iterator ===
The functional implementation restated as an imperative iterator, also adjusted to not allocate a new result table on each iteration; this saves time, but makes mutating the returned table unsafe.
<syntaxhighlight lang="lua">local function cartesian_product(sets)
local item_counts = {}
local indices = {}
Line 2,770 ⟶ 2,741:
=== Functional-esque (non-iterator) ===
Motivation: If a list-of-lists is passed into the cartesian product, then wouldn't a list-of-lists be the expected return type? Of course this is just personal opinion/preference, other implementations are fine as-is if you'd rather have an iterator.
<syntaxhighlight lang="lua">-- support:
function T(t) return setmetatable(t, {__index=table}) end
table.clone = function(t) local s=T{} for k,v in ipairs(t) do s[k]=v end return s end
Line 2,810 ⟶ 2,781:
{(1, 30, 500), (1, 30, 100), (2, 30, 500), (2, 30, 100), (3, 30, 500), (3, 30, 100)}
{}</pre>
 
=={{header|Maple}}==
<syntaxhighlight lang=Maple"maple">
cartmulti := proc ()
local m, v;
Line 2,825 ⟶ 2,795:
end proc;
</syntaxhighlight>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang=Mathematica"mathematica">cartesianProduct[args__] := Flatten[Outer[List, args], Length[{args}] - 1]</syntaxhighlight>
 
=={{header|Modula-2}}==
<syntaxhighlight lang="modula2">MODULE CartesianProduct;
FROM FormatString IMPORT FormatString;
FROM Terminal IMPORT WriteString,WriteLn,ReadChar;
Line 2,879 ⟶ 2,847:
ReadChar
END CartesianProduct.</syntaxhighlight>
 
=={{header|Nim}}==
===Task: product of two lists===
Line 2,888 ⟶ 2,855:
In order to display the result using mathematical formalism, we have created a special procedure “$$” for the sequences and have overloaded the procedure “$” for tuples.
 
<syntaxhighlight lang=Nim"nim">iterator product[T1, T2](a: openArray[T1]; b: openArray[T2]): tuple[a: T1, b: T2] =
# Yield the element of the cartesian product of "a" and "b".
# Yield tuples rather than arrays as it allows T1 and T2 to be different.
Line 2,942 ⟶ 2,909:
Note that there exists in the standard module “algorithm” a procedure which computes the product of sequences of a same type. It is not recursive and, so, likely more efficient that the following version.
 
<syntaxhighlight lang=Nim"nim">proc product[T](a: varargs[seq[T]]): seq[seq[T]] =
## Return the product of several sets (sequences).
 
Line 2,973 ⟶ 2,940:
With a macro, we are able to mix several value types: the “varrags” is no longer a problem as being used at compile time it may contain sequences of different types. And we are able to return tuples of n values instead of sequences of n values.
 
<syntaxhighlight lang=Nim"nim">import macros
 
macro product(args: varargs[typed]): untyped =
Line 3,050 ⟶ 3,017:
{{out}}
<pre>{1, 2} x {a, b} x {false, true} = {(1, a, false], (1, a, true], (1, b, false], (1, b, true], (2, a, false], (2, a, true], (2, b, false], (2, b, true]}</pre>
 
=={{header|OCaml}}==
''The double semicolons are necessary only for the toplevel''
 
Naive but more readable version<syntaxhighlight lang="ocaml">let rec product l1 l2 =
match l1, l2 with
| [], _ | _, [] -> []
Line 3,070 ⟶ 3,036:
 
Implementation with a bit more tail-call optimization, introducing a helper function. The order of the result is changed but it should not be an issue for most uses.
<syntaxhighlight lang="ocaml">let product' l1 l2 =
let rec aux ~acc l1' l2' =
match l1', l2' with
Line 3,090 ⟶ 3,056:
(*- : ('a * int) list = []*)</syntaxhighlight>
Implemented using nested folds:
<syntaxhighlight lang="ocaml">let cart_prod l1 l2 =
List.fold_left (fun acc1 ele1 ->
List.fold_left (fun acc2 ele2 -> (ele1,ele2)::acc2) acc1 l2) [] l1 ;;
Line 3,100 ⟶ 3,066:
 
Extra credit function. Since in OCaml a function can return only one type, and because tuples of different arities are different types, this returns a list of lists rather than a list of tuples. Since lists are homogeneous this version is restricted to products over a ''single'' type, eg integers.
<syntaxhighlight lang="ocaml">let rec product'' l =
(* We need to do the cross product of our current list and all the others
* so we define a helper function for that *)
Line 3,150 ⟶ 3,116:
 
In the latter example, our function has this signature:
<syntaxhighlight lang="ocaml">val product'' : 'a list list -> 'a list list = <fun></syntaxhighlight>
This lacks clarity as those two lists are not equivalent since one replaces a tuple. We can get a better signature by creating a tuple type:
<syntaxhighlight lang="ocaml">type 'a tuple = 'a list
 
let rec product'' (l:'a list tuple) =
Line 3,174 ⟶ 3,140:
type 'a tuple = 'a list
val product'' : 'a list tuple -> 'a tuple list = <fun></syntaxhighlight>
 
=={{header|Perl}}==
==== Iterative ====
Nested loops, with a short-circuit to quit early if any term is an empty set.
<syntaxhighlight lang="perl">sub cartesian {
my $sets = shift @_;
for (@$sets) { return [] unless @$_ }
Line 3,221 ⟶ 3,186:
==== Glob ====
This being Perl, there's more than one way to do it. A quick demonstration of how <code>glob</code>, more typically used for filename wildcard expansion, can solve the task.
<syntaxhighlight lang="perl">$tuples = [ map { [split /:/] } glob '{1,2,3}:{30}:{500,100}' ];
 
for $a (@$tuples) { printf "(%1d %2d %3d) ", @$a; }</syntaxhighlight>
Line 3,229 ⟶ 3,194:
==== Modules ====
A variety of modules can do this correctly for an arbitrary number of lists (each of independent length). Arguably using modules is very idiomatic Perl.
<syntaxhighlight lang="perl">use ntheory qw/forsetproduct/;
forsetproduct { say "@_" } [1,2,3],[qw/a b c/],[qw/@ $ !/];
 
Line 3,240 ⟶ 3,205:
use Algorithm::Loops qw/NestedLoops/;
NestedLoops([[1,2,3],[qw/a b c/],[qw/@ $ !/]], sub { say "@_"; });</syntaxhighlight>
 
=={{header|Phix}}==
<!--<syntaxhighlight lang=Phix"phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">cart</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
Line 3,280 ⟶ 3,244:
{}
</pre>
 
=={{header|Phixmonti}}==
<syntaxhighlight lang=Phixmonti"phixmonti">include ..\Utilitys.pmt
 
def cart
Line 3,313 ⟶ 3,276:
( ( 1 2 ) ( ) ) cart
drop res print nl nl</syntaxhighlight>
 
=={{header|PicoLisp}}==
<syntaxhighlight lang=PicoLisp"picolisp">(de 2lists (L1 L2)
(mapcan
'((I)
Line 3,350 ⟶ 3,312:
((1 30 500) (1 30 100) (2 30 500) (2 30 100) (3 30 500) (3 30 100))
NIL</pre>
 
=={{header|Prolog}}==
<syntaxhighlight lang=Prolog"prolog">
product([A|_], Bs, [A, B]) :- member(B, Bs).
product([_|As], Bs, X) :- product(As, Bs, X).
Line 3,372 ⟶ 3,333:
=={{header|Python}}==
===Using itertools===
<syntaxhighlight lang="python">import itertools
 
def cp(lsts):
Line 3,437 ⟶ 3,398:
If we write ourselves a re-usable Python '''ap''' function for the case of lists (applicative functions for other 'data containers' can also be written – this one applies a list of functions to a list of values):
 
<syntaxhighlight lang="python"># ap (<*>) :: [(a -> b)] -> [a] -> [b]
def ap(fs):
return lambda xs: foldl(
Line 3,446 ⟶ 3,407:
then one simple use of it will be to define the cartesian product of two lists (of possibly different type) as:
 
<syntaxhighlight lang="python">ap(map(Tuple, xs))</syntaxhighlight>
 
where Tuple is a constructor, and xs is bound to the first of two lists. The returned value is a function which can be applied to a second list.
Line 3,452 ⟶ 3,413:
For an nAry product, we can then use a '''fold''' (catamorphism) to lift the basic function over two lists ''cartesianProduct :: [a] -> [b] -> [(a, b)]'' to a function over a list of lists:
 
<syntaxhighlight lang="python"># nAryCartProd :: [[a], [b], [c] ...] -> [(a, b, c ...)]
def nAryCartProd(xxs):
return foldl1(cartesianProduct)(
Line 3,460 ⟶ 3,421:
For example:
 
<syntaxhighlight lang="python"># Two lists -> list of tuples
 
 
Line 3,603 ⟶ 3,564:
[(1, 30, 500), (1, 30, 100), (2, 30, 500), (2, 30, 100), (3, 30, 500), (3, 30, 100)]
[]</pre>
 
=={{header|Quackery}}==
 
<syntaxhighlight lang=Quackery"quackery"> [ [] unrot
swap witheach
[ over witheach
Line 3,627 ⟶ 3,587:
[ ]
</pre>
 
=={{header|R}}==
 
<syntaxhighlight lang=R"r">
one_w_many <- function(one, many) lapply(many, function(x) c(one,x))
 
Line 3,652 ⟶ 3,611:
Simple tests:
 
<syntaxhighlight lang=R"r">
> display_prod( c(1, 2) %p% c(3, 4) )
1, 3
Line 3,669 ⟶ 3,628:
Tougher tests:
 
<syntaxhighlight lang=R"r">
go( c(1776, 1789), c(7, 12), c(4, 14, 23), c(0, 1) )
go( c(1, 2, 3), c(30), c(500, 100) )
Line 3,713 ⟶ 3,672:
(1, 2, 3) * () * (500, 100)
</pre>
 
=={{header|Racket}}==
 
Racket has a built-in "cartesian-product" function:
 
<syntaxhighlight lang="text">#lang racket/base
(require rackunit
;; usually, included in "racket", but we're using racket/base so we
Line 3,764 ⟶ 3,722:
'((1 30 500) (1 30 100) (2 30 500) (2 30 100) (3 30 500) (3 30 100))
'()</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
Line 3,770 ⟶ 3,727:
The cross meta operator X will return the cartesian product of two lists. To apply the cross meta-operator to a variable number of lists, use the reduce cross meta operator [X].
 
<syntaxhighlight lang="raku" line># cartesian product of two lists using the X cross meta-operator
say (1, 2) X (3, 4);
say (3, 4) X (1, 2);
Line 3,789 ⟶ 3,746:
((1 30 500) (1 30 100) (2 30 500) (2 30 100) (3 30 500) (3 30 100))
()</pre>
 
=={{header|REXX}}==
===version 1===
This REXX version isn't limited by the number of lists or the number of sets within a list.
<syntaxhighlight lang="rexx">/*REXX program calculates the Cartesian product of two arbitrary-sized lists. */
@.= /*assign the default value to @. array*/
parse arg @.1 /*obtain the optional value of @.1 */
Line 3,830 ⟶ 3,786:
 
===version 2===
<syntaxhighlight lang="rexx">/* REXX computes the Cartesian Product of up to 4 sets */
Call cart '{1, 2} x {3, 4}'
Call cart '{3, 4} x {1, 2}'
Line 3,949 ⟶ 3,905:
{1, 2, 3} x {} x {500, 100}
{}</pre>
 
=={{header|Ring}}==
<syntaxhighlight lang="ring">
# Project : Cartesian product of two or more lists
 
Line 3,979 ⟶ 3,934:
(4, 2)
</pre>
 
=={{header|Ruby}}==
"product" is a method of arrays. It takes one or more arrays as argument and results in the Cartesian product:
<syntaxhighlight lang="ruby">p [1, 2].product([3, 4])
p [3, 4].product([1, 2])
p [1, 2].product([])
Line 3,998 ⟶ 3,952:
[]
</pre>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">fn cartesian_product(lists: &Vec<Vec<u32>>) -> Vec<Vec<u32>> {
let mut res = vec![];
 
Line 4,063 ⟶ 4,016:
[]
</pre>
 
=={{header|Scala}}==
Function returning the n-ary product of an arbitrary number of lists, each of arbitrary length:
 
<syntaxhighlight lang="scala">def cartesianProduct[T](lst: List[T]*): List[List[T]] = {
 
/**
Line 4,098 ⟶ 4,050:
}</syntaxhighlight>
and usage:
<syntaxhighlight lang="scala">cartesianProduct(List(1, 2), List(3, 4))
.map(_.mkString("(", ", ", ")")).mkString("{",", ","}")</syntaxhighlight>
{{out}}
<pre>{(1, 3), (1, 4), (2, 3), (2, 4)}</pre>
 
<syntaxhighlight lang="scala">cartesianProduct(List(3, 4), List(1, 2))
.map(_.mkString("(", ", ", ")")).mkString("{",", ","}")</syntaxhighlight>
{{out}}
<pre>{(3, 1), (3, 2), (4, 1), (4, 2)}</pre>
 
<syntaxhighlight lang="scala">cartesianProduct(List(1, 2), List.empty)
.map(_.mkString("(", ", ", ")")).mkString("{",", ","}")</syntaxhighlight>
{{out}}
<pre>{}</pre>
 
<syntaxhighlight lang="scala">cartesianProduct(List.empty, List(1, 2))
.map(_.mkString("(", ", ", ")")).mkString("{",", ","}")</syntaxhighlight>
{{out}}
<pre>{}</pre>
 
<syntaxhighlight lang="scala">cartesianProduct(List(1776, 1789), List(7, 12), List(4, 14, 23), List(0, 1))
.map(_.mkString("(", ", ", ")")).mkString("{",", ","}")</syntaxhighlight>
{{out}}
<pre>{(1776, 7, 4, 0), (1776, 7, 4, 1), (1776, 7, 14, 0), (1776, 7, 14, 1), (1776, 7, 23, 0), (1776, 7, 23, 1), (1776, 12, 4, 0), (1776, 12, 4, 1), (1776, 12, 14, 0), (1776, 12, 14, 1), (1776, 12, 23, 0), (1776, 12, 23, 1), (1789, 7, 4, 0), (1789, 7, 4, 1), (1789, 7, 14, 0), (1789, 7, 14, 1), (1789, 7, 23, 0), (1789, 7, 23, 1), (1789, 12, 4, 0), (1789, 12, 4, 1), (1789, 12, 14, 0), (1789, 12, 14, 1), (1789, 12, 23, 0), (1789, 12, 23, 1)}</pre>
 
<syntaxhighlight lang="scala">cartesianProduct(List(1, 2, 3), List(30), List(500, 100))
.map(_.mkString("(", ", ", ")")).mkString("{",", ","}")</syntaxhighlight>
{{out}}
<pre>{(1, 30, 500), (1, 30, 100), (2, 30, 500), (2, 30, 100), (3, 30, 500), (3, 30, 100)}</pre>
 
<syntaxhighlight lang="scala">cartesianProduct(List(1, 2, 3), List.empty, List(500, 100))
.map(_.mkString("[", ", ", "]")).mkString("\n")</syntaxhighlight>
{{out}}
<pre>{}</pre>
 
=={{header|Scheme}}==
<syntaxhighlight lang="scheme">
(define cartesian-product (lambda (xs ys)
(if (or (zero? (length xs)) (zero? (length ys)))
Line 4,156 ⟶ 4,107:
((1 a x) (1 a y) (1 b x) (1 b y) (2 a x) (2 a y) (2 b x) (2 b y))
</syntaxhighlight>
 
=={{header|Sidef}}==
In Sidef, the Cartesian product of an arbitrary number of arrays is built-in as ''Array.cartesian()'':
<syntaxhighlight lang="ruby">cartesian([[1,2], [3,4], [5,6]]).say
cartesian([[1,2], [3,4], [5,6]], {|*arr| say arr })</syntaxhighlight>
 
Alternatively, a simple recursive implementation:
<syntaxhighlight lang="ruby">func cartesian_product(*arr) {
 
var c = []
Line 4,185 ⟶ 4,135:
 
Completing the task:
<syntaxhighlight lang="ruby">say cartesian_product([1,2], [3,4])
say cartesian_product([3,4], [1,2])</syntaxhighlight>
{{out}}
Line 4,193 ⟶ 4,143:
</pre>
The product of an empty list with any other list is empty:
<syntaxhighlight lang="ruby">say cartesian_product([1,2], [])
say cartesian_product([], [1,2])</syntaxhighlight>
{{out}}
Line 4,201 ⟶ 4,151:
</pre>
Extra credit:
<syntaxhighlight lang="ruby">cartesian_product([1776, 1789], [7, 12], [4, 14, 23], [0, 1]).each{ .say }</syntaxhighlight>
{{out}}
<pre>
Line 4,230 ⟶ 4,180:
</pre>
 
<syntaxhighlight lang="ruby">say cartesian_product([1, 2, 3], [30], [500, 100])
say cartesian_product([1, 2, 3], [], [500, 100])</syntaxhighlight>
{{out}}
Line 4,237 ⟶ 4,187:
[]
</pre>
 
=={{header|SQL}}==
If we create lists as tables with one column, cartesian product is easy.
<syntaxhighlight lang="sql">-- set up list 1
create table L1 (value integer);
insert into L1 values (1);
Line 4,256 ⟶ 4,205:
1 4
2 3
2 4</pre>You should be able to be more explicit should get the same result:<syntaxhighlight lang="sql">select * from L1 cross join L2;</syntaxhighlight>
Product with an empty list works as expected (using the tables created above):
<syntaxhighlight lang="sql">delete from L2;
select * from L1, L2;</syntaxhighlight>
{{out}}
<pre>no rows selected</pre>
I don't think "extra credit" is meaningful here because cartesian product is so hard-baked into SQL, so here's just one of the extra credit examples (again using the tables created above):<syntaxhighlight lang="sql">insert into L1 values (3);
insert into L2 values (30);
create table L3 (value integer);
Line 4,278 ⟶ 4,227:
2 30 100
3 30 100</pre>
 
=={{header|Standard ML}}==
<syntaxhighlight lang="sml">fun prodList (nil, _) = nil
| prodList ((x::xs), ys) = map (fn y => (x,y)) ys @ prodList (xs, ys)
 
Line 4,307 ⟶ 4,255:
- naryProdList [[1, 2, 3], [], [500, 100]];
val it = [] : int list list</pre>
 
=={{header|Stata}}==
 
In Stata, the command '''[https://www.stata.com/help.cgi?fillin fillin]''' may be used to expand a dataset with all combinations of a number of variables. Thus it's easy to compute a cartesian product.
 
<syntaxhighlight lang="stata">. list
 
+-------+
Line 4,335 ⟶ 4,282:
The other way around:
 
<syntaxhighlight lang="stata">. list
 
+-------+
Line 4,358 ⟶ 4,305:
Note, however, that this is not equivalent to a cartesian product when one of the variables is "empty" (that is, only contains missing values).
 
<syntaxhighlight lang="stata">. list
 
+-------+
Line 4,379 ⟶ 4,326:
This command works also if the varaibles have different numbers of nonmissing elements. However, this requires additional code to remove the observations with missing values.
 
<syntaxhighlight lang="stata">. list
 
+-----------+
Line 4,435 ⟶ 4,382:
6. | 3 5 6 1 |
+---------------------+</syntaxhighlight>
 
=={{header|Swift}}==
 
{{trans|Scala}}
 
<syntaxhighlight lang="swift">func + <T>(el: T, arr: [T]) -> [T] {
var ret = arr
 
Line 4,492 ⟶ 4,438:
[[1, 30, 500], [1, 30, 100], [2, 30, 500], [2, 30, 100], [3, 30, 500], [3, 30, 100]]
[]</pre>
 
=={{header|Tailspin}}==
<syntaxhighlight lang="tailspin">
'{1,2}x{3,4} = $:[by [1,2]..., by [3,4]...];
' -> !OUT::write
Line 4,531 ⟶ 4,476:
year {1776, 1789} × month {7, 12} × day {4, 14, 23} = {day=4, month=7, year=1776}{day=4, month=7, year=1789}{day=4, month=12, year=1776}{day=4, month=12, year=1789}{day=14, month=7, year=1776}{day=14, month=7, year=1789}{day=14, month=12, year=1776}{day=14, month=12, year=1789}{day=23, month=7, year=1776}{day=23, month=7, year=1789}{day=23, month=12, year=1776}{day=23, month=12, year=1789}
</pre>
 
=={{header|Tcl}}==
<syntaxhighlight lang="tcl">
proc cartesianProduct {l1 l2} {
set result {}
Line 4,582 ⟶ 4,526:
result:
</pre>
 
=={{header|UNIX Shell}}==
The UNIX shells don't allow passing or returning arrays from functions (other than pass-by-name shenanigans), but as pointed out in the Perl entry, wildcard brace expansion (in bash, ksh, zsh) does a Cartesian product if there's more than one set of alternatives. It doesn't handle the empty-list case (an empty brace expansion item is treated as a single item that is equal to the empty string), but otherwise it works:
Line 4,624 ⟶ 4,567:
(3,30,500)
(3,30,100)
 
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<syntaxhighlight lang="vbnet">Imports System.Runtime.CompilerServices
 
Module Module1
Line 4,673 ⟶ 4,614:
{(1, 30, 500), (1, 30, 100), (2, 30, 500), (2, 30, 100), (3, 30, 500), (3, 30, 100)}
{}</pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-seq}}
<syntaxhighlight lang="ecmascript">import "/seq" for Lst
 
var prod2 = Fn.new { |l1, l2|
Line 4,772 ⟶ 4,712:
]
</pre>
 
=={{header|zkl}}==
Cartesian product is build into iterators or can be done with nested
loops.
<syntaxhighlight lang="zkl">zkl: Walker.cproduct(List(1,2),List(3,4)).walk().println();
L(L(1,3),L(1,4),L(2,3),L(2,4))
zkl: foreach a,b in (List(1,2),List(3,4)){ print("(%d,%d) ".fmt(a,b)) }
Line 4,786 ⟶ 4,725:
The walk method will throw an error if used on an empty iterator but the pump
method doesn't.
<syntaxhighlight lang="zkl">zkl: Walker.cproduct(List(3,4),List).walk().println();
Exception thrown: TheEnd(Ain't no more)
 
Line 4,793 ⟶ 4,732:
zkl: Walker.cproduct(List,List(3,4)).pump(List).println();
L()</syntaxhighlight>
<syntaxhighlight lang="zkl">zkl: Walker.cproduct(L(1776,1789),L(7,12),L(4,14,23),L(0,1)).walk().println();
L(L(1776,7,4,0),L(1776,7,4,1),L(1776,7,14,0),L(1776,7,14,1),L(1776,7,23,0),L(1776,7,23,1),L(1776,12,4,0),L(1776,12,4,1),L(1776,12,14,0),L(1776,12,14,1),L(1776,12,23,0),L(1776,12,23,1),L(1789,7,4,0),L(1789,7,4,1),L(1789,7,14,0),L(1789,7,14,1),L(1789,7,23,0),L(1789,7,23,1),L(1789,12,4,0),L(1789,12,4,1),...)
 
10,327

edits