Cartesian product of two or more lists: Difference between revisions

m
(→‎{{header|Tailspin}}: Use new cartesian product feature)
 
(39 intermediate revisions by 22 users not shown)
Line 21:
 
<br>
 
=={{header|11l}}==
{{trans|Go}}
<langsyntaxhighlight lang="11l">F cart_prod(a, b)
V p = [(0, 0)] * (a.len * b.len)
V i = 0
Line 36 ⟶ 35:
[Int] empty_array
print(cart_prod([1, 2], empty_array))
print(cart_prod(empty_array, [1, 2]))</langsyntaxhighlight>
====Alternative version====
<langsyntaxhighlight lang="11l">F cart_prod(a, b)
R multiloop(a, b, (aa, bb) -> (aa, bb))</langsyntaxhighlight>
{{out}}
<pre>
Line 46 ⟶ 45:
[]
[]
</pre>
=={{header|Action!}}==
<syntaxhighlight lang="action!">DEFINE MAX_COUNT="10"
DEFINE MAX_RESULT="100"
 
DEFINE PTR="CARD"
 
PROC PrintInput(PTR ARRAY a INT count)
INT i,j,n
INT ARRAY tmp
 
FOR i=0 TO count-1
DO
tmp=a(i) n=tmp(0)
Put('[)
FOR j=1 TO n
DO
PrintI(tmp(j))
IF j<n THEN Put(',) FI
OD
Put('])
IF i<count-1 THEN Put('x) FI
OD
RETURN
 
PROC PrintOutput(INT ARRAY a INT groups,count)
INT i,j,k
 
Put('[)
k=0
FOR i=0 TO groups-1
DO
Put('()
FOR j=0 TO count-1
DO
PrintI(a(k)) k==+1
IF j<count-1 THEN Put(',) FI
OD
Put('))
IF i<groups-1 THEN Put(',) FI
OD
Put('])
RETURN
 
PROC Product(PTR ARRAY a INT count
INT ARRAY r INT POINTER groups)
INT ARRAY ind(MAX_COUNT),tmp
INT i,j,k
 
IF count>MAX_COUNT THEN Break() FI
groups^=1
FOR i=0 TO count-1
DO
ind(i)=1 tmp=a(i)
groups^==*tmp(0)
OD
IF groups^=0 THEN RETURN FI
j=count-1 k=0
DO
FOR i=0 TO count-1
DO
tmp=a(i)
r(k)=tmp(ind(i)) k==+1
OD
 
DO
tmp=a(j)
IF ind(j)<tmp(0) THEN
ind(j)==+1
FOR i=j+1 TO count-1
DO
ind(i)=1
OD
j=count-1
EXIT
ELSE
IF j=0 THEN RETURN FI
j==-1
FI
OD
OD
RETURN
 
PROC Test(PTR ARRAY a INT count)
INT ARRAY r(MAX_RESULT)
INT groups
 
IF count<2 THEN Break() FI
Product(a,count,r,@groups)
PrintInput(a,count)
Put('=)
PrintOutput(r,groups,count)
PutE()
RETURN
 
PROC Main()
INT ARRAY
a1=[2 1 2],a2=[2 3 4],a3=[0],
a4=[2 1776 1789],a5=[2 7 12],
a6=[3 4 14 23],a7=[2 0 1],
a8=[3 1 2 3],a9=[1 30],a10=[2 500 100]
PTR ARRAY a(4)
 
a(0)=a1 a(1)=a2 Test(a,2)
a(0)=a2 a(1)=a1 Test(a,2)
a(0)=a1 a(1)=a3 Test(a,2)
a(0)=a3 a(1)=a1 Test(a,2) PutE()
a(0)=a4 a(1)=a5 a(2)=a6 a(3)=a7 Test(a,4) PutE()
a(0)=a8 a(1)=a9 a(2)=a10 Test(a,3) PutE()
a(0)=a8 a(1)=a3 a(2)=a10 Test(a,3)
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Cartesian_product_of_two_or_more_lists.png Screenshot from Atari 8-bit computer]
<pre>
[1,2]x[3,4]=[(1,3),(1,4),(2,3),(2,4)]
[3,4]x[1,2]=[(3,1),(3,2),(4,1),(4,2)]
[1,2]x[]=[]
[]x[1,2]=[]
[1776,1789]x[7,12]x[4,14,23]x[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)]
[1,2,3]x[30]x[500,100]=[(1,30,500),(1,30,100),(2,30,500),(2,30,100),(3,30,500),(3,30,100)]
[1,2,3]x[]x[500,100]=[]
</pre>
=={{header|Ada}}==
<syntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_Io;
with Ada.Containers.Doubly_Linked_Lists;
with Ada.Strings.Fixed;
 
procedure Cartesian is
 
type Element_Type is new Long_Integer;
 
package Lists is
new Ada.Containers.Doubly_Linked_Lists (Element_Type);
package List_Lists is
new Ada.Containers.Doubly_Linked_Lists (Lists.List, Lists."=");
 
subtype List is Lists.List;
subtype List_List is List_Lists.List;
 
function "*" (Left, Right : List) return List_List is
Result : List_List;
Sub : List;
begin
for Outer of Left loop
for Inner of Right loop
Sub.Clear;
Sub.Append (Outer);
Sub.Append (Inner);
Result.Append (Sub);
end loop;
end loop;
return Result;
end "*";
 
function "*" (Left : List_List;
Right : List) return List_List
is
Result : List_List;
Sub : List;
begin
for Outer of Left loop
for Inner of Right loop
Sub := Outer;
Sub.Append (Inner);
Result.Append (Sub);
end loop;
end loop;
return Result;
end "*";
 
procedure Put (L : List) is
use Ada.Strings;
First : Boolean := True;
begin
Put ("(");
for E of L loop
if not First then
Put (",");
end if;
Put (Fixed.Trim (E'Image, Left));
First := False;
end loop;
Put (")");
end Put;
 
procedure Put (LL : List_List) is
First : Boolean := True;
begin
Put ("{");
for E of LL loop
if not First then
Put (",");
end if;
Put (E);
First := False;
end loop;
Put ("}");
end Put;
 
function "&" (Left : List; Right : Element_Type) return List is
Result : List := Left;
begin
Result.Append (Right);
return Result;
end "&";
 
Nil : List renames Lists.Empty_List;
List_1_2 : constant List := Nil & 1 & 2;
List_3_4 : constant List := Nil & 3 & 4;
List_Empty : constant List := Nil;
List_1_2_3 : constant List := Nil & 1 & 2 & 3;
begin
Put (List_1_2 * List_3_4); New_Line;
 
Put (List_3_4 * List_1_2); New_Line;
 
Put (List_Empty * List_1_2); New_Line;
 
Put (List_1_2 * List_Empty); New_Line;
 
Put (List'(Nil & 1776 & 1789) * List'(Nil & 7 & 12) *
List'(Nil & 4 & 14 & 23) * List'(Nil & 0 & 1)); New_Line;
 
Put (List_1_2_3 * List'(Nil & 30) * List'(Nil & 500 & 100)); New_Line;
 
Put (List_1_2_3 * List_Empty * List'(Nil & 500 & 100)); New_Line;
end Cartesian;</syntaxhighlight>
{{out}}
<pre>{(1,3),(1,4),(2,3),(2,4)}
{(3,1),(3,2),(4,1),(4,2)}
{}
{}
{(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)}
{(1,30,500),(1,30,100),(2,30,500),(2,30,100),(3,30,500),(3,30,100)}
{}</pre>
=={{header|ALGOL 68}}==
Using a 1-dimensional array of INT to represent a list and a 2-dimensional array ( [,]INT ) to represent a product of two (or more) lists.
<br>
A list of lists is represented by a 1-dimensional array of 1-dimensional arrays of INT ([][]INT).
<syntaxhighlight lang="algol68">
BEGIN # Cartesian Product #
# Cartesian product operators #
PRIO X = 7; # give X he same priority as * #
# returns the Cartesian product of the lists a and b #
OP X = ( []INT a, b )[,]INT:
BEGIN
[]INT a1 = a[ AT 1 ];
[]INT b1 = b[ AT 1 ];
INT len = UPB a1 * UPB b1;
[ 1 : len, 1 : IF len > 0 THEN 2 ELSE 0 FI ]INT result;
INT pos := 0;
FOR i TO UPB a1 DO
FOR j TO UPB b1 DO
pos +:= 1;
result[ pos, 1 ] := a1[ i ];
result[ pos, 2 ] := b1[ j ]
OD
OD;
result
END # X # ;
# returns the Cartesian product of the Cartesian product a and list b #
OP X = ( [,]INT a, []INT b )[,]INT:
BEGIN
[,]INT a1 = a[ AT 1, AT 1 ];
[]INT b1 = b[ AT 1 ];
INT len = 1 UPB a1 * UPB b1;
INT width = IF len <= 0 THEN 0 ELSE 2 UPB a1 + 1 FI;
[ 1 : len, 1 : width ]INT result;
INT pos := 0;
FOR i TO 1 UPB a1 DO
FOR j TO UPB b1 DO
result[ pos +:= 1, 1 : width - 1 ] := a1[ i, : ];
result[ pos, width ] := b1[ j ]
OD
OD;
result
END # X # ;
# returns the Cartesian product of the lists in a #
OP X = ( [][]INT a )[,]INT:
IF UPB a <= LWB a
THEN # zero or 1 list #
[,]INT()
ELSE # 2 or more lists #
FLEX[ 1 : 0, 1 : 0 ]INT result := a[ LWB a ] X a[ LWB a + 1 ];
FOR i FROM LWB a + 2 TO UPB a DO
result := result X a[ i ]
OD;
result
FI # X # ;
# print a Cartesian product #
PROC print product = ( [,]INT p )VOID:
BEGIN
print( ( "[" ) );
STRING close := "]";
STRING open := "(";
FOR i FROM 1 LWB p TO 1 UPB p DO
STRING separator := open;
FOR j FROM 2 LWB p TO 2 UPB p DO
print( ( separator, whole( p[ i, j ], 0 ) ) );
separator := ","
OD;
open := "),(";
close := ")]"
OD;
print( ( close ) )
END # print product # ;
# print a list #
PROC print list = ( []INT t )VOID:
BEGIN
print( ( "[" ) );
STRING separator := "";
FOR i FROM LWB t TO UPB t DO
print( ( separator, whole( t[ i ], 0 ) ) );
separator := ","
OD;
print( ( "]" ) )
END # print list # ;
BEGIN # test the X operators #
# prints the product of two lists #
PROC print lxl = ( []INT a, b )VOID:
BEGIN
print list( a );print( ( "X" ) );print list( b );
print( ( "=" ) );print product( a X b );
print( ( newline ) )
END # print lxl # ;
# prints the product of a list of lists #
PROC print xll = ( [][]INT a )VOID:
IF LWB a < UPB a THEN
# non empty list of lists #
print list( a[ LWB a ] );
FOR i FROM LWB a + 1 TO UPB a DO
print( ( "X" ) );print list( a[ i ] )
OD;
print( ( "=" ) );print product( X a );
print( ( newline ) )
FI # print xll # ;
print lxl( ( 1, 2 ), ( 3, 4 ) );
print lxl( ( 3, 4 ), ( 1, 2 ) );
print lxl( ( 1, 2 ), () );
print lxl( (), ( 1, 2 ) );
print xll( ( ( 1776, 1789 ), ( 7, 12 ), ( 4, 14, 23 ), ( 0, 1 ) ) );
print xll( ( ( 1, 2, 3 ), ( 30 ), ( 500, 100 ) ) );
print xll( ( ( 1, 2, 3 ), (), ( 500, 100 ) ) )
END
END
</syntaxhighlight>
{{out}}
<pre>
[1,2]X[3,4]=[(1,3),(1,4),(2,3),(2,4)]
[3,4]X[1,2]=[(3,1),(3,2),(4,1),(4,2)]
[1,2]X[]=[]
[]X[1,2]=[]
[1776,1789]X[7,12]X[4,14,23]X[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)]
[1,2,3]X[30]X[500,100]=[(1,30,500),(1,30,100),(2,30,500),(2,30,100),(3,30,500),(3,30,100)]
[1,2,3]X[]X[500,100]=[]
</pre>
 
Line 56 ⟶ 411:
a matrix, and the task is asking for a list, you also need to ravel the result.
 
<syntaxhighlight lang APL="apl">cart ← ,∘.,</langsyntaxhighlight>
 
{{out}}
Line 73 ⟶ 428:
list of lists.
 
<langsyntaxhighlight APLlang="apl">nary_cart ← ⊃(,∘.,)/</langsyntaxhighlight>
 
{{out}}
Line 116 ⟶ 471:
 
=={{header|AppleScript}}==
<langsyntaxhighlight AppleScriptlang="applescript">-- CARTESIAN PRODUCTS ---------------------------------------------------------
 
-- Two lists:
Line 275 ⟶ 630:
on unlines(xs)
intercalate(linefeed, xs)
end unlines</langsyntaxhighlight>
{{Out}}
<pre>[[1, 3], [1, 4], [2, 3], [2, 4]]
Line 310 ⟶ 665:
 
[]</pre>
=={{header|Arturo}}==
{{trans|Ruby}}
<syntaxhighlight lang="rebol">loop [
[[1 2][3 4]]
[[3 4][1 2]]
[[1 2][]]
[[][1 2]]
[[1776 1789][7 12][4 14 23][0 1]]
[[1 2 3][30][500 100]]
[[1 2 3][][500 100]]
] 'lst [
print as.code product.cartesian lst
]</syntaxhighlight>
 
{{out}}
 
<pre>[[1 3] [1 4] [2 3] [2 4]]
[[3 1] [3 2] [4 1] [4 2]]
[]
[]
[[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]]
[[1 30 500] [1 30 100] [2 30 500] [2 30 100] [3 30 500] [3 30 100]]
[]</pre>
=={{header|AutoHotkey}}==
<syntaxhighlight lang="autohotkey">example := [
(join,
[[1, 2], [3, 4]]
[[3, 4], [1, 2]]
[[1, 2], []]
[[], [1, 2]]
[[1776, 1789], [7, 12], [4, 14, 23], [0, 1]]
[[1, 2, 3], [30] , [500, 100]]
[[1, 2, 3], [] , [500, 100]]
)]
 
for i, obj in example
{
Product := CartesianProduct(obj)
out := dispRes(Product)
result .= out "`n`n"
}
MsgBox % result
return
 
dispRes(Product){
for i, o in Product
{
for j, v in o
output .= v ", "
output := Trim(output, ", ")
output .= "], ["
}
return "[[" trim(output, ", []") "]]"
}
 
CartesianProduct(obj){
CP(obj, Product:=[], [])
return Product
}
 
CP(obj, Product, stack, v:=""){
oClone := obj.clone()
oClone.RemoveAt(1)
stack.= v ","
for i, o in obj
{
for j, v in o
CP(oClone, Product, stack, v)
return
}
stack := trim(stack, ",")
oTemp := []
for i, v in StrSplit(stack, ",")
oTemp.Push(v)
Product.push(oTemp)
}</syntaxhighlight>
{{out}}
<pre>[[1, 3], [1, 4], [2, 3], [2, 4]]
[[3, 1], [3, 2], [4, 1], [4, 2]]
[]
[]
[[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]]
[[1, 30, 500], [1, 30, 100], [2, 30, 500], [2, 30, 100], [3, 30, 500], [3, 30, 100]]
[]</pre>
=={{header|Bracmat}}==
<langsyntaxhighlight Bracmatlang="bracmat">( ( mul
= R a b A B
. :?R
Line 346 ⟶ 786:
& out$(cartprod$((.1 2 3) (.30) (.500 100)))
& out$(cartprod$((.1 2 3) (.) (.500 100)))
)</langsyntaxhighlight>
<pre>. (.1776 7 4 0)
(.1776 7 4 1)
Line 379 ⟶ 819:
(.3 30 100)
.</pre>
 
=={{header|BASIC}}==
==={{header|Applesoft BASIC}}===
{{works with|Chipmunk Basic}}
{{works with|GW-BASIC}}
<syntaxhighlight lang="qbasic">100 HOME : rem 10 CLS FOR Chipmunk Basic & GW-BASIC
110 DIM array(2,2)
120 array(1,1) = 1 : array(1,2) = 2
130 array(2,1) = 3 : array(2,2) = 4
140 GOSUB 190
150 array(1,1) = 3 : array(1,2) = 4
160 array(2,1) = 1 : array(2,2) = 2
170 GOSUB 190
180 END
190 rem SUB cartesian(list)
200 u1 = 2 : u2 = 2
210 FOR i = 1 TO u1
220 PRINT "{ ";
230 FOR j = 1 TO u2
240 PRINT array(i,j);
250 IF j < u1 THEN PRINT ", ";
260 NEXT j
270 PRINT "}";
280 IF i < u2 THEN PRINT " x ";
290 NEXT i
300 PRINT " = { ";
310 FOR i = 1 TO u1
320 FOR j = 1 TO u2
330 PRINT "{ "; array(1,i); ", "; array(2,j); "} ";
340 IF i < u2 THEN PRINT ", ";
350 IF i => u2 THEN IF j < u1 THEN PRINT ", ";
360 NEXT j
370 NEXT i
380 PRINT "}"
390 RETURN</syntaxhighlight>
 
==={{header|BASIC256}}===
<syntaxhighlight lang="vb">arraybase 1
subroutine cartesian(list)
u1 = list[?][]
u2 = list[][?]
 
for i = 1 to u1
print "{";
for j = 1 to u2
print list[i,j];
if j < u1 then print ", ";
next
print "}";
if i < u2 then print " x ";
next i
print " = { ";
for i = 1 to u1
for j = 1 to u2
print "{"; list[1, i]; ", "; list[2, j]; "} ";
if i < u2 then
print ", ";
else
if j < u1 then print ", ";
end if
next j
next i
print "}"
end subroutine
 
dim list1 = {{1,2},{3,4}}
dim list2 = {{3,4},{1,2}}
call cartesian(list1)
call cartesian(list2)
end</syntaxhighlight>
{{out}}
<pre>{1, 2} x {3, 4} = { {1, 3} , {1, 4} , {2, 3} , {2, 4} }
{3, 4} x {1, 2} = { {3, 1} , {3, 2} , {4, 1} , {4, 2} }</pre>
 
==={{header|Chipmunk Basic}}===
{{works with|Chipmunk Basic|3.6.4}}
<syntaxhighlight lang="qbasic">100 cls
110 dim array(2,2)
120 array(1,1) = 1 : array(1,2) = 2
130 array(2,1) = 3 : array(2,2) = 4
140 gosub 190
150 array(1,1) = 3 : array(1,2) = 4
160 array(2,1) = 1 : array(2,2) = 2
170 gosub 190
180 end
190 rem sub cartesian(list)
200 u1 = 2 : u2 = 2
210 for i = 1 to u1
220 print "{ ";
230 for j = 1 to u2
240 print array(i,j);
250 if j < u1 then print ", ";
260 next j
270 print "}";
280 if i < u2 then print " x ";
290 next i
300 print " = { ";
310 for i = 1 to u1
320 for j = 1 to u2
330 print "{ ";array(1,i);", ";array(2,j);"} ";
340 if i < u2 then
350 print ", ";
360 else
370 if j < u1 then print ", ";
380 endif
390 next j
400 next i
410 print "}"
420 return</syntaxhighlight>
 
==={{header|Gambas}}===
<syntaxhighlight lang="vbnet">Public array[2, 2] As Integer
 
Public Sub Main()
array[0, 0] = 1
array[0, 1] = 2
array[1, 0] = 3
array[1, 1] = 4
cartesian(array)
array[0, 0] = 3
array[0, 1] = 4
array[1, 0] = 1
array[1, 1] = 2
cartesian(array)
End
 
Sub cartesian(arr As Integer[])
Dim u1 As Integer = arr.Max - 2
Dim u2 As Integer = arr.Max - 2
Dim i As Integer, j As Integer
For i = 0 To u1
Print "{";
For j = 0 To u2
Print arr[i, j];
If j < u1 Then Print ",";
Next
Print "}";
If i < u2 Then Print " x ";
Next
Print " = {";
For i = 0 To u1
For j = 0 To u2
Print "{"; arr[0, i]; ","; arr[1, j]; "}";
If i < u2 Then
Print ", ";
Else
If j < u1 Then Print ", ";
End If
Next
Next
Print "}"
End Sub</syntaxhighlight>
 
==={{header|GW-BASIC}}===
{{works with|Chipmunk Basic}}
{{works with|PC-BASIC|any}}
{{works with|QBasic}}
{{works with|MSX-BASIC}}
<syntaxhighlight lang="qbasic">100 CLS
110 DIM ARR(2,2)
120 ARR(1,1) = (1) : ARR(1,2) = (2)
130 ARR(2,1) = (3) : ARR(2,2) = (4)
140 GOSUB 190
150 ARR(1,1) = 3 : ARR(1,2) = 4
160 ARR(2,1) = 1 : ARR(2,2) = 2
170 GOSUB 190
180 END
190 REM SUB cartesian(list)
200 U1 = 2 : U2 = 2
210 FOR I = 1 TO U1
220 PRINT "{";
230 FOR J = 1 TO U2
240 PRINT ARR(I,J);
250 IF J < U1 THEN PRINT ",";
260 NEXT J
270 PRINT "}";
280 IF I < U2 THEN PRINT " x ";
290 NEXT I
300 PRINT " = {";
310 FOR I = 1 TO U1
320 FOR J = 1 TO U2
330 PRINT "{"; ARR(1,I); ","; ARR(2,J); "}";
340 IF I < U2 THEN PRINT ", ";
350 IF I => U2 THEN IF J < U1 THEN PRINT ",";
360 NEXT J
370 NEXT I
380 PRINT "}"
390 RETURN</syntaxhighlight>
 
==={{header|MSX Basic}}===
{{works with|MSX BASIC|any}}
The [[#GW-BASIC|GW-BASIC]] solution works without any changes.
 
==={{header|QBasic}}===
{{works with|QBasic|1.1}}
{{works with|QuickBasic|4.5}}
<syntaxhighlight lang="qbasic">DECLARE SUB cartesian (arr!())
 
CLS
DIM array(2, 2)
array(1, 1) = 1: array(1, 2) = 2
array(2, 1) = 3: array(2, 2) = 4
CALL cartesian(array())
array(1, 1) = 3: array(1, 2) = 4
array(2, 1) = 1: array(2, 2) = 2
CALL cartesian(array())
END
 
SUB cartesian (arr())
u1 = 2: u2 = 2
FOR i = 1 TO u1
PRINT "{";
FOR j = 1 TO u2
PRINT arr(i, j);
IF j < u1 THEN PRINT ",";
NEXT j
PRINT "}";
IF i < u2 THEN PRINT " x ";
NEXT i
PRINT " = {";
FOR i = 1 TO u1
FOR j = 1 TO u2
PRINT "{"; arr(1, i); ","; arr(2, j); "}";
IF i < u2 THEN
PRINT ", ";
ELSE
IF j < u1 THEN PRINT ", ";
END IF
NEXT j
NEXT i
PRINT "}"
END SUB</syntaxhighlight>
 
==={{header|Run BASIC}}===
{{works with|Just BASIC}}
{{works with|Liberty BASIC}}
<syntaxhighlight lang="vb">cls
dim array(2,2)
array(1,1) = 1 : array(1,2) = 2
array(2,1) = 3 : array(2,2) = 4
gosub [cartesian]
array(1,1) = 3 : array(1,2) = 4
array(2,1) = 1 : array(2,2) = 2
gosub [cartesian]
end
 
[cartesian]
u1 = 2 : u2 = 2
for i = 1 to u1
print "{";
for j = 1 to u2
print array(i,j);
if j < u1 then print ",";
next j
print "}";
if i < u2 then print " x ";
next i
print " = {";
for i = 1 to u1
for j = 1 to u2
print "{"; array(1,i); ","; array(2,j); "}";
if i < u2 then
print ",";
else
if j < u1 then print ",";
end if
next j
next i
print "}"
return</syntaxhighlight>
 
=={{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">
<lang C>
#include<string.h>
#include<stdlib.h>
Line 499 ⟶ 1,214:
return 0;
}
</syntaxhighlight>
</lang>
Invocation and output :
<pre>
Line 524 ⟶ 1,239:
{}
</pre>
=={{header|C sharp|C#}}==
 
<syntaxhighlight lang="csharp">using System;
=={{header|C sharp}}==
<lang csharp>using System;
public class Program
{
Line 569 ⟶ 1,283:
select acc.Concat(new [] { item }));
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 580 ⟶ 1,294:
{}</pre>
If the number of lists is known, LINQ provides an easier solution:
<langsyntaxhighlight lang="csharp">public static void Main()
{
///...
Line 595 ⟶ 1,309:
select (a, b, c);
Console.WriteLine($"{{{string.Join(", ", cart2)}}}");
}</langsyntaxhighlight>
{{out}}
<pre>
Line 601 ⟶ 1,315:
{(1, 30, 500), (1, 30, 100), (2, 30, 500), (2, 30, 100), (3, 30, 500), (3, 30, 100)}
</pre>
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">
#include <iostream>
#include <vector>
Line 659 ⟶ 1,372:
std::cin.get();
return 0;
}</langsyntaxhighlight>
 
{{out}}
Line 669 ⟶ 1,382:
{ (1 30 500) (1 30 100) (2 30 500) (2 30 100) (3 30 500) (3 30 100) }
{ }</pre>
 
=={{header|Clojure}}==
<syntaxhighlight lang="clojure">
<lang Clojure>
(ns clojure.examples.product
(:gen-class)
Line 683 ⟶ 1,395:
x (first colls)]
(cons x more))))
</syntaxhighlight>
</lang>
'''Output'''
<langsyntaxhighlight lang="clojure">
(doseq [lst [ [[1,2],[3,4]],
[[3,4],[1,2]], [[], [1, 2]],
Line 696 ⟶ 1,408:
(println lst "=>")
(pp/pprint (cart lst)))
</syntaxhighlight>
</lang>
 
<pre>
Line 737 ⟶ 1,449:
()
</pre>
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">(defun cartesian-product (s1 s2)
"Compute the cartesian product of two sets represented as lists"
(loop for x in s1
nconc (loop for y in s2 collect (list x y))))
</syntaxhighlight>
</lang>
 
'''Output'''
 
<langsyntaxhighlight lang="lisp">
CL-USER> (cartesian-product '(1 2) '(3 4))
((1 3) (1 4) (2 3) (2 4))
Line 756 ⟶ 1,467:
CL-USER> (cartesian-product '() '(1 2))
NIL
</syntaxhighlight>
</lang>
 
'''Extra credit:'''
 
<langsyntaxhighlight 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 770 ⟶ 1,481:
(loop for x in (car l)
nconc (loop for y in (n-cartesian-product (cdr l))
collect (cons x y)))))</langsyntaxhighlight>
 
'''Output:'''
 
<langsyntaxhighlight 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 780 ⟶ 1,491:
CL-USER> (n-cartesian-product '((1 2 3) () (500 100)))
NIL
</syntaxhighlight>
</lang>
 
=={{header|Crystal}}==
The first function is the basic task. The version overloaded for one argument is the extra credit task, implemented using recursion.
<langsyntaxhighlight lang="crystal">def cartesian_product(a, b)
return a.flat_map { |i| b.map { |j| [i, j] } }
end
Line 817 ⟶ 1,527:
puts ""
}
</syntaxhighlight>
</lang>
 
{{out}}
Line 841 ⟶ 1,551:
[[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}}==
<langsyntaxhighlight Dlang="d">import std.stdio;
 
void main() {
Line 881 ⟶ 1,590:
 
return Result();
}</langsyntaxhighlight>
 
{{out}}
Line 888 ⟶ 1,597:
[]
[]</pre>
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{Trans|Go}}
<syntaxhighlight lang="delphi">
program Cartesian_product_of_two_or_more_lists;
 
{$APPTYPE CONSOLE}
 
uses
System.SysUtils;
 
type
TList = TArray<Integer>;
 
TLists = TArray<TList>;
 
TListHelper = record helper for TList
function ToString: string;
end;
 
TListsHelper = record helper for TLists
function ToString(BreakLines: boolean = false): string;
end;
 
function cartN(arg: TLists): TLists;
var
b, n: TList;
argc: Integer;
begin
argc := length(arg);
 
var c := 1;
for var a in arg do
c := c * length(a);
 
if c = 0 then
exit;
 
SetLength(result, c);
SetLength(b, c * argc);
SetLength(n, argc);
 
var s := 0;
for var i := 0 to c - 1 do
begin
var e := s + argc;
var Resi := copy(b, s, e - s);
Result[i] := Resi;
 
s := e;
for var j := 0 to high(n) do
begin
var nj := n[j];
Resi[j] := arg[j, nj];
end;
 
for var j := high(n) downto 0 do
begin
inc(n[j]);
if n[j] < Length(arg[j]) then
Break;
n[j] := 0;
end;
end;
end;
 
{ TListHelper }
 
function TListHelper.ToString: string;
begin
Result := '[';
for var i := 0 to High(self) do
begin
Result := Result + self[i].ToString;
if i < High(self) then
Result := Result + ' ';
end;
Result := Result + ']';
end;
 
{ TListsHelper }
 
function TListsHelper.ToString(BreakLines: boolean = false): string;
begin
Result := '[';
for var i := 0 to High(self) do
begin
Result := Result + self[i].ToString;
if i < High(self) then
begin
if BreakLines then
Result := Result + #10
else
Result := Result + ' ';
end;
end;
Result := Result + ']';
end;
 
begin
writeln(#10, cartN([[1, 2], [3, 4]]).ToString);
writeln(#10, cartN([[3, 4], [1, 2]]).ToString);
writeln(#10, cartN([[1, 2], []]).ToString);
writeln(#10, cartN([[], [1, 2]]).ToString);
 
writeln(#10, cartN([[1776, 1789], [17, 12], [4, 14, 23], [0, 1]]).ToString(True));
 
writeln(#10, cartN([[1, 2, 3], [30], [500, 100]]).ToString);
 
writeln(#10, cartN([[1, 2, 3], [], [500, 100]]).ToString);
 
{$IFNDEF UNIX} readln; {$ENDIF}
end.</syntaxhighlight>
{{out}}
<pre>[[1 3] [1 4] [2 3] [2 4]]
 
[[3 1] [3 2] [4 1] [4 2]]
 
[]
 
[]
 
[[1776 17 4 0]
[1776 17 4 1]
[1776 17 14 0]
[1776 17 14 1]
[1776 17 23 0]
[1776 17 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 17 4 0]
[1789 17 4 1]
[1789 17 14 0]
[1789 17 14 1]
[1789 17 23 0]
[1789 17 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]]
 
[[1 30 500] [1 30 100] [2 30 500] [2 30 100] [3 30 500] [3 30 100]]
 
[]</pre>
=={{header|EasyLang}}==
{{trans|Go}}
<syntaxhighlight>
proc cart2 a[] b[] . p[][] .
p[][] = [ ]
for a in a[]
for b in b[]
p[][] &= [ a b ]
.
.
.
cart2 [ 1 2 ] [ 3 4 ] r[][]
print r[][]
cart2 [ 3 4 ] [ 1 2 ] r[][]
print r[][]
cart2 [ 1 2 ] [ ] r[][]
print r[][]
cart2 [ ] [ 1 2 ] r[][]
print r[][]
</syntaxhighlight>
 
=={{header|Erlang}}==
Can do this with list comprehensions.
<syntaxhighlight lang="erlang">
-module(cartesian).
-export([product/2]).
 
product(S1, S2) -> [{A,B} || A <- S1, B <- S2].
</syntaxhighlight>
{{Out}}
<pre>
2> cartesian:product([],[1,2,3]).
[]
3> cartesian:product([1,2,3],[]).
[]
4> cartesian:product([1,2],[3,4]).
[{1,3},{1,4},{2,3},{2,4}]
5> cartesian:product([3,4],[1,2]).
[{3,1},{3,2},{4,1},{4,2}]
</pre>
 
=={{header|F Sharp|F#}}==
===The Task===
<langsyntaxhighlight lang="fsharp">
//Nigel Galloway February 12th., 2018
let cP2 n g = List.map (fun (n,g)->[n;g]) (List.allPairs n g)
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 904 ⟶ 1,803:
 
===Extra Credit===
<langsyntaxhighlight 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 [[]]
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 925 ⟶ 1,824:
 
=={{header|Factor}}==
<langsyntaxhighlight Factorlang="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 932 ⟶ 1,831:
{ { } { } }
IN: scratchpad { } { 1 2 } cartesian-product .
{ }</langsyntaxhighlight>
=={{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.
! ifort -o cartesian_product cartesian_product.f90 -check all
module tuple
implicit none
private
public :: tuple_t, operator(*), print
type tuple_t(n)
integer, len :: n
integer, private :: v(n)
contains
procedure, public :: print => print_tuple_t
generic, public :: assignment(=) => eq_tuple_t
procedure, public :: eq_tuple_t
end type tuple_t
interface print
module procedure print_tuple_a_t
end interface print
interface operator(*)
module procedure tup_times_tup
end interface
contains
subroutine eq_tuple_t(this, src)
class(tuple_t(*)), intent(inout) :: this
integer, intent(in) :: src(:)
this%v = src
end subroutine eq_tuple_t
 
pure function tup_times_tup(a, b) result(r)
type(tuple_t(*)), intent(in) :: a
type(tuple_t(*)), intent(in) :: b
type(tuple_t(2)), allocatable :: r(:)
integer :: i, j, k
allocate(r(a%n*b%n))
k = 0
do i=1,a%n
do j=1,b%n
k = k + 1
r(k)%v = [a%v(i),b%v(j)]
end do
end do
end function tup_times_tup
subroutine print_tuple_t(this)
class(tuple_t(*)), intent(in) :: this
integer :: i
write(*,fmt='(a)',advance='no') '{'
do i=1,size(this%v)
write(*,fmt='(i0)',advance='no') this%v(i)
if (i < size(this%v)) write(*,fmt='(a)',advance='no') ','
end do
write(*,fmt='(a)',advance='no') '}'
end subroutine print_tuple_t
subroutine print_tuple_a_t(r)
type(tuple_t(*)), intent(in) :: r(:)
integer :: i
write(*,fmt='(a)',advance='no') '{'
do i=1,size(r)
call r(i)%print
if (i < size(r)) write(*,fmt='(a)',advance='no') ','
end do
write(*,fmt='(a)') '}'
end subroutine print_tuple_a_t
end module tuple
program cartesian_product
use tuple
implicit none
type(tuple_t(2)) :: a, b
type(tuple_t(0)) :: z
a = [1,2]
b = [3,4]
call print_product(a, b)
call print_product(b, a)
call print_product(z, a)
call print_product(a, z)
stop
contains
subroutine print_product(s, t)
type(tuple_t(*)), intent(in) :: s
type(tuple_t(*)), intent(in) :: t
call s%print
write(*,fmt='(a)',advance='no') ' x '
call t%print
write(*,fmt='(a)',advance='no') ' = '
call print(s*t)
end subroutine print_product
end program cartesian_product
</syntaxhighlight>
{{out}}
<pre> {1,2} x {3,4} = {{1,3},{1,4},{2,3},{2,4}}
{3,4} x {1,2} = {{3,1},{3,2},{4,1},{4,2}}
{1,2} x {} = {}
{} x {1,2} = {}</pre>
 
=={{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.
 
<langsyntaxhighlight lang="freebasic">#define MAXLEN 64
 
type listitem ' An item of a list may be a number
Line 998 ⟶ 2,005:
R = cartprod(B, A) : print_list(R) : print
R = cartprod(A, EMPTY) : print_list(R) : print
R = cartprod(EMPTY, A) : print_list(R) : print</langsyntaxhighlight>
{{out}}<pre>{{1, 3}, {1, 4}, {2, 3}, {2, 4}}
{{3, 1}, {3, 2}, {4, 1}, {4, 2}}
Line 1,007 ⟶ 2,014:
=={{header|Fōrmulæ}}==
 
In [http{{FormulaeEntry|page=https://wiki.formulae.org/?script=examples/Cartesian_product_of_two_or_more_lists this] page you can see the solution of this task.}}
 
'''Solution'''
Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text ([http://wiki.formulae.org/Editing_F%C5%8Drmul%C3%A6_expressions more info]). Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation &mdash;i.e. XML, JSON&mdash; they are intended for transportation effects more than visualization and edition.
 
No program is needed, the cartesian product is an intrinsic operation in Fōrmulæ
The option to show Fōrmulæ programs and their results is showing images. Unfortunately images cannot be uploaded in Rosetta Code.
 
'''Test case 1.''' No commutativity
 
[[File:Fōrmulæ - Cartesian product of two or more lists 01.png]]
 
[[File:Fōrmulæ - Cartesian product of two or more lists 02.png]]
 
[[File:Fōrmulæ - Cartesian product of two or more lists 03.png]]
 
[[File:Fōrmulæ - Cartesian product of two or more lists 04.png]]
 
'''Test case 2.''' With an empty list
 
[[File:Fōrmulæ - Cartesian product of two or more lists 05.png]]
 
[[File:Fōrmulæ - Empty list.png]]
 
[[File:Fōrmulæ - Cartesian product of two or more lists 06.png]]
 
[[File:Fōrmulæ - Empty list.png]]
 
'''Test case 3.''' Extra credit. n-ary cartesian product
 
[[File:Fōrmulæ - Cartesian product of two or more lists 07.png]]
 
[[File:Fōrmulæ - Cartesian product of two or more lists 08.png]]
 
[[File:Fōrmulæ - Cartesian product of two or more lists 09.png]]
 
[[File:Fōrmulæ - Cartesian product of two or more lists 10.png]]
 
[[File:Fōrmulæ - Cartesian product of two or more lists 11.png]]
 
[[File:Fōrmulæ - Empty list.png]]
 
=={{header|Go}}==
'''Basic Task'''
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 1,038 ⟶ 2,079:
fmt.Println(cart2([]int{1, 2}, nil))
fmt.Println(cart2(nil, []int{1, 2}))
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,049 ⟶ 2,090:
 
This solution minimizes allocations and computes and fills the result sequentially.
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 1,107 ⟶ 2,148:
fmt.Println(cartN(nil))
fmt.Println(cartN())
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,150 ⟶ 2,191:
 
Code here is more compact, but with the cost of more garbage produced. It produces the same result as cartN above.
<langsyntaxhighlight lang="go">func cartN(a ...[]int) (c [][]int) {
if len(a) == 0 {
return [][]int{nil}
Line 1,161 ⟶ 2,202:
}
return
}</langsyntaxhighlight>
'''Extra credit 3'''
 
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.
<langsyntaxhighlight lang="go">func cartN(a ...[]int) (c [][]int) {
if len(a) == 0 {
return [][]int{nil}
Line 1,177 ⟶ 2,218:
}
return
}</langsyntaxhighlight>
 
=={{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''.
<langsyntaxhighlight lang="groovy">class CartesianCategory {
static Iterable multiply(Iterable a, Iterable b) {
assert [a,b].every { it != null }
Line 1,188 ⟶ 2,228:
(0..<(m*n)).inject([]) { prod, i -> prod << [a[i.intdiv(n)], b[i%n]].flatten() }
}
}</langsyntaxhighlight>
'''Test:'''<br>
The ''mixin'' method call is necessary to make the multiply (*) operator work.
<langsyntaxhighlight lang="groovy">Iterable.metaClass.mixin CartesianCategory
 
println "\nCore Solution:"
Line 1,207 ⟶ 2,247:
println "[John,Paul,George,Ringo] × [Emerson,Lake,Palmer] × [Simon,Garfunkle] = ["
( ["John","Paul","George","Ringo"] * ["Emerson","Lake","Palmer"] * ["Simon","Garfunkle"] ).each { println "\t${it}," }
println "]"</langsyntaxhighlight>
'''Output:'''
<pre>
Line 1,248 ⟶ 2,288:
[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:
<langsyntaxhighlight Haskelllang="haskell">cartProd :: [a] -> [b] -> [(a, b)]
cartProd xs ys =
[ (x, y)
| x <- xs
, y <- ys ]</langsyntaxhighlight>
 
more directly:
<langsyntaxhighlight Haskelllang="haskell">cartProd :: [a] -> [b] -> [(a, b)]
cartProd xs ys = xs >>= \x -> ys >>= \y -> [(x, y)]</langsyntaxhighlight>
 
applicatively:
<langsyntaxhighlight Haskelllang="haskell">cartProd :: [a] -> [b] -> [(a, b)]
cartProd xs ys = (,) <$> xs <*> ys</langsyntaxhighlight>
 
parsimoniously:
<langsyntaxhighlight Haskelllang="haskell">cartProd :: [a] -> [b] -> [(a, b)]
cartProd = (<*>) . fmap (,)</langsyntaxhighlight>
 
We might test any of these with:
<langsyntaxhighlight lang="haskell">main :: IO ()
main =
mapM_ print $
uncurry cartProd <$>
[([1, 2], [3, 4]), ([3, 4], [1, 2]), ([1, 2], []), ([], [1, 2])]</langsyntaxhighlight>
{{Out}}
<pre>[(1,3),(1,4),(2,3),(2,4)]
Line 1,284 ⟶ 2,323:
 
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,
<langsyntaxhighlight lang="haskell">cartProdN :: [[a]] -> [[a]]
cartProdN = sequence
 
main :: IO ()
main = print $ cartProdN [[1, 2], [3, 4], [5, 6]]</langsyntaxhighlight>
{{Out}}
<pre>[[1,3,5],[1,3,6],[1,4,5],[1,4,6],[2,3,5],[2,3,6],[2,4,5],[2,4,6]]</pre>
 
or we could define ourselves an equivalent function over a list of lists in terms of a fold, for example as:
<langsyntaxhighlight lang="haskell">cartProdN :: [[a]] -> [[a]]
cartProdN = foldr (\xs as -> xs >>= (<$> as) . (:)) [[]]</langsyntaxhighlight>
or, equivalently, as:
<langsyntaxhighlight lang="haskell">cartProdN :: [[a]] -> [[a]]
cartProdN = foldr
(\xs as ->
Line 1,302 ⟶ 2,341:
| x <- xs
, a <- as ])
[[]]</langsyntaxhighlight>
testing any of these with something like:
<langsyntaxhighlight lang="haskell">main :: IO ()
main = do
mapM_ print $
Line 1,311 ⟶ 2,350:
print $ cartProdN [[1,2,3], [30], [500, 100]]
putStrLn ""
print $ cartProdN [[1,2,3], [], [500, 100]]</langsyntaxhighlight>
{{Out}}
<pre>[1776,7,4,0]
Line 1,341 ⟶ 2,380:
 
[]</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).
<langsyntaxhighlight 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,386 ⟶ 2,424:
└───────┴────────┘
{ 1 2 3 ; '' ; 50 100 NB. result is an empty 3-dimensional array with shape 3 0 2
</syntaxhighlight>
</lang>
 
=={{header|Java}}==
{{works with|Java Virtual Machine|1.8}}
<syntaxhighlight lang="java">
<lang Java>
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
Line 1,419 ⟶ 2,456:
}
}
</syntaxhighlight>
</lang>
 
'''Using a generic class with a recursive function'''
<syntaxhighlight lang="java">
<lang Java>
import java.util.ArrayList;
import java.util.Arrays;
Line 1,478 ⟶ 2,515:
}
}
</syntaxhighlight>
</lang>
 
=={{header|JavaScript}}==
function cartesian(m){
if(!m.length)return[[]];
let tails=cartesian(m.slice(1));
return(m[0].flatMap(h=>tails.map(t=>[h].concat(t))));
}
 
===ES6===
====Functional====
Line 1,486 ⟶ 2,528:
 
For the Cartesian product of just two lists:
<langsyntaxhighlight JavaScriptlang="javascript">(() => {
// CARTESIAN PRODUCT OF TWO LISTS ---------------------
 
Line 1,501 ⟶ 2,543:
cartProd([])([1, 2]),
].map(JSON.stringify).join('\n');
})();</langsyntaxhighlight>
{{Out}}
<pre>[[1,3],[1,4],[2,3],[2,4]]
Line 1,510 ⟶ 2,552:
 
Abstracting a little more, we can define the cartesian product quite economically in terms of a general applicative operator:
<langsyntaxhighlight Javascriptlang="javascript">(() => {
 
// CARTESIAN PRODUCT OF TWO LISTS ---------------------
Line 1,548 ⟶ 2,590:
.map(JSON.stringify)
.join('\n');
})();</langsyntaxhighlight>
{{Out}}
<pre>[[1,3],[1,4],[2,3],[2,4]]
Line 1,556 ⟶ 2,598:
 
For the n-ary Cartesian product over a list of lists:
<langsyntaxhighlight JavaScriptlang="javascript">(() => {
const main = () => {
// n-ary Cartesian product of a list of lists.
Line 1,616 ⟶ 2,658:
 
return main();
})();</langsyntaxhighlight>
{{Out}}
<pre>[1776,7,4,0]
Line 1,650 ⟶ 2,692:
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''':
 
<langsyntaxhighlight JavaScriptlang="javascript">(() => {
// n-ary Cartesian product of a list of lists
// ( Imperative implementation )
Line 1,723 ⟶ 2,765:
]))
]);
})();</langsyntaxhighlight>
{{Out}}
<pre>[[1,4],[1,3],[2,4],[2,3]]
Line 1,765 ⟶ 2,807:
 
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">
<lang jq>
def products: .[0][] as $x | .[1][] as $y | [$x,$y];
</syntaxhighlight>
</lang>
 
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">
<lang jq>
def product: [products];
</syntaxhighlight>
</lang>
 
For the sake of brevity, two illustrations should suffice:
Line 1,787 ⟶ 2,829:
 
And
<syntaxhighlight lang="jq">
<lang jq>
[[1,2], []] | product
</syntaxhighlight>
</lang>
produces:
<pre>
Line 1,798 ⟶ 2,840:
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">
<lang jq>
def cartesians:
if length <= 2 then products
Line 1,805 ⟶ 2,847:
| [$x] + $y
end;
</syntaxhighlight>
</lang>
 
Again for brevity, in the following, we will just show the number of items in the Cartesian products:
Line 1,817 ⟶ 2,859:
[[1, 2, 3], [], [500, 100] ] | [cartesians] | length
# 0
 
=={{header|Julia}}==
Run in REPL.
<langsyntaxhighlight lang="julia">
# Product {1, 2} × {3, 4}
collect(Iterators.product([1, 2], [3, 4]))
Line 1,837 ⟶ 2,878:
# Product {1, 2, 3} × {} × {500, 100}
collect(Iterators.product([1, 2, 3], [], [500, 100]))
</syntaxhighlight>
</lang>
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1.2
 
fun flattenList(nestList: List<Any>): List<Any> {
Line 1,892 ⟶ 2,932:
printNAryProduct(listOf(listOf(1, 2, 3), listOf<Int>(), listOf(500, 100)))
printNAryProduct(listOf(listOf(1, 2, 3), listOf(30), listOf('a', 'b')))
}</langsyntaxhighlight>
 
{{out}}
Line 1,955 ⟶ 2,995:
]
</pre>
 
=={{header|langur}}==
<syntaxhighlight lang="langur">val .X = fn(... .x) { .x }
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.
 
writeln mapX(.X, [1, 2], [3, 4]) == [[1, 3], [1, 4], [2, 3], [2, 4]]
{{works with|langur|0.8.3}}
<lang langur>writeln XmapX(.X, [13, 24], [31, 42]) == [[13, 31], [13, 42], [24, 31], [24, 42]]
writeln mapX(.X([3, 4], [1, 2]) == [[3, 1], [3, 2],) [4, 1],== [4, 2]]
writeln XmapX([1.X, 2[], [1, 2]) == []
writeln X([], [1, 2]) == []
writeln()
 
writeln mapX .X, [1776, 1789], [7, 12], [4, 14, 23], [0, 1]
writeln()
 
writeln mapX .X, [1, 2, 3], [30], [500, 100]
writeln()
 
writeln mapX .X, [1, 2, 3], [], [500, 100]
writeln()</langsyntaxhighlight>
 
{{out}}
Line 1,991 ⟶ 3,029:
=== Functional ===
An iterator is created to output the product items.
<langsyntaxhighlight 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,040 ⟶ 3,078:
print(i,a,b)
end
</syntaxhighlight>
</lang>
{{out}}
<pre>1 1 3
Line 2,056 ⟶ 3,094:
 
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.
<langsyntaxhighlight lang="lua">local function cartesian_product(sets)
local result = {}
local set_count = #sets
Line 2,104 ⟶ 3,142:
print(" " .. format_nested_list(product))
end
end</langsyntaxhighlight>
 
=== 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.
<langsyntaxhighlight lang="lua">local function cartesian_product(sets)
local item_counts = {}
local indices = {}
Line 2,181 ⟶ 3,219:
print(i, format_nested_list(product))
end
end</langsyntaxhighlight>
 
=== 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
table.reduce = function(t,f,acc) for i=1,#t do acc=f(t[i],acc) end return acc end
 
-- implementation:
local function cartprod(sets)
local temp, prod = T{}, T{}
local function descend(depth)
for _,v in ipairs(sets[depth]) do
temp[depth] = v
if (depth==#sets) then prod[#prod+1]=temp:clone() else descend(depth+1) end
end
end
descend(1)
return prod
end
 
-- demonstration:
tests = {
{ {1, 2}, {3, 4} },
{ {3, 4}, {1, 2} },
{ {1, 2}, {} },
{ {}, {1, 2} },
{ {1776, 1789}, {7, 12}, {4, 14, 23}, {0, 1} },
{ {1, 2, 3}, {30}, {500, 100} },
{ {1, 2, 3}, {}, {500, 100} }
}
for _,test in ipairs(tests) do
local cp = cartprod(test)
print("{"..cp:reduce(function(t,a) return (a=="" and a or a..", ").."("..t:concat(", ")..")" end,"").."}")
end</syntaxhighlight>
{{out}}
<pre>{(1, 3), (1, 4), (2, 3), (2, 4)}
{(3, 1), (3, 2), (4, 1), (4, 2)}
{}
{}
{(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)}
{(1, 30, 500), (1, 30, 100), (2, 30, 500), (2, 30, 100), (3, 30, 500), (3, 30, 100)}
{}</pre>
=={{header|Maple}}==
<syntaxhighlight lang="maple">
<lang Maple>
cartmulti := proc ()
local m, v;
Line 2,196 ⟶ 3,276:
end if;
end proc;
</syntaxhighlight>
</lang>
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">cartesianProduct[args__] := Flatten[Outer[List, args], Length[{args}] - 1]</syntaxhighlight>
 
=={{header|Maxima}}==
Using built-in function cartesian_product
<syntaxhighlight lang="maxima">
cartesian_product({1,2},{3,4});
/* {[1,3],[1,4],[2,3],[2,4]} */
cartesian_product({3,4},{1,2});
/* {[3,1],[3,2],[4,1],[4,2]} */
cartesian_product({1,2},{});
/* {} */
cartesian_product({},{1,2});
/* {} */
</syntaxhighlight>
Using built-in function cartesian_product_list
<syntaxhighlight lang="maxima">
cartesian_product_list([1,2],[3,4]);
/* [[1,3],[1,4],[2,3],[2,4]] */
cartesian_product_list([3,4],[1,2]);
/* [[3,1],[3,2],[4,1],[4,2]] */
cartesian_product_list([1,2],[]);
/* [] */
cartesian_product_list([],[1,2]);
/* [] */
</syntaxhighlight>
Using built-in function create_list
<syntaxhighlight lang="maxima">
create_list([i,j],i,[1,2],j,[3,4]);
/* [[1,3],[1,4],[2,3],[2,4]] */
create_list([i,j],i,[3,4],j,[1,2]);
/* [[3,1],[3,2],[4,1],[4,2]] */
create_list([i,j],i,[1,2],j,[]);
/* [] */
create_list([i,j],i,[],j,[1,2]);
/* [] */
</syntaxhighlight>
Extra credit
<syntaxhighlight lang="maxima">
my_cartesian(lst1,lst2):=create_list([i,j],i,lst1,j,lst2);
n_ary_cartesian(singleargument):=block(lreduce(my_cartesian,singleargument),map(flatten,%%));
 
[[1776,1789],[7,12],[4,14,23],[0,1]]$
n_ary_cartesian(%);
/* [[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]] */
 
[[1,2,3],[30],[500,100]]$
n_ary_cartesian(%);
/* [[1,30,500],[1,30,100],[2,30,500],[2,30,100],[3,30,500],[3,30,100]] */
 
[[1,2,3],[],[500,100]]$
=={{header|Mathematica}}==
n_ary_cartesian(%);
<lang Mathematica>cartesianProduct[args__] := Flatten[Outer[List, args], Length[{args}] - 1]</lang>
/* [] */
</syntaxhighlight>
 
=={{header|Modula-2}}==
<langsyntaxhighlight lang="modula2">MODULE CartesianProduct;
FROM FormatString IMPORT FormatString;
FROM Terminal IMPORT WriteString,WriteLn,ReadChar;
Line 2,250 ⟶ 3,381:
 
ReadChar
END CartesianProduct.</langsyntaxhighlight>
 
=={{header|Nim}}==
===Task: product of two lists===
Line 2,260 ⟶ 3,390:
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.
 
<langsyntaxhighlight Nimlang="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,299 ⟶ 3,429:
( Empty, @[1, 2])]:
 
echo &"{$$a} x {$$b} = {$$toSeq(product(a, b))}"</langsyntaxhighlight>
 
{{out}}
Line 2,314 ⟶ 3,444:
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.
 
<langsyntaxhighlight Nimlang="nim">proc product[T](a: varargs[seq[T]]): seq[seq[T]] =
## Return the product of several sets (sequences).
 
Line 2,335 ⟶ 3,465:
b = @[3, 4]
c = @[5, 6]
echo &"{a} x {b} x {c} = {product(a, b, c)}"</langsyntaxhighlight>
 
{{out}}
Line 2,345 ⟶ 3,475:
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.
 
<langsyntaxhighlight Nimlang="nim">import macros
 
macro product(args: varargs[typed]): untyped =
Line 2,418 ⟶ 3,548:
var b = @['a', 'b']
var c = @[false, true]
echo &"{$$a} x {$$b} x {$$c} = {$$product(a, b, c)}"</langsyntaxhighlight>
 
{{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<langsyntaxhighlight lang="ocaml">let rec product l1 l2 =
match l1, l2 with
| [], _ | _, [] -> []
Line 2,439 ⟶ 3,568:
(*- : (int * 'a) list = []*)
product [] [1;2];;
(*- : ('a * int) list = []*)</langsyntaxhighlight>
 
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.
<langsyntaxhighlight lang="ocaml">let product' l1 l2 =
let rec aux ~acc l1' l2' =
match l1', l2' with
Line 2,460 ⟶ 3,589:
(*- : (int * 'a) list = []*)
product' [] [1;2];;
(*- : ('a * int) list = []*)</langsyntaxhighlight>
Implemented using nested folds:
<langsyntaxhighlight 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 2,469 ⟶ 3,598:
(*- : (int * char) list = [(3, 'c'); (3, 'b'); (3, 'a'); (2, 'c'); (2, 'b'); (2, 'a'); (1, 'c'); (1, 'b'); (1, 'a')]*)
cart_prod [1; 2; 3] [] ;;
(*- : ('a * int) list = [] *)</langsyntaxhighlight>
 
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.
<langsyntaxhighlight 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 2,517 ⟶ 3,646:
*)
product'' [[1; 2; 3];[];[500; 100]];;
(*- : int list list = []*)</langsyntaxhighlight>
 
=== Better type ===
 
In the latter example, our function has this signature:
<langsyntaxhighlight lang="ocaml">val product'' : 'a list list -> 'a list list = <fun></langsyntaxhighlight>
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:
<langsyntaxhighlight lang="ocaml">type 'a tuple = 'a list
 
let rec product'' (l:'a list tuple) =
Line 2,545 ⟶ 3,674:
 
type 'a tuple = 'a list
val product'' : 'a list tuple -> 'a tuple list = <fun></langsyntaxhighlight>
 
=={{header|Perl}}==
==== Iterative ====
Nested loops, with a short-circuit to quit early if any term is an empty set.
<langsyntaxhighlight lang="perl">sub cartesian {
my $sets = shift @_;
for (@$sets) { return [] unless @$_ }
Line 2,581 ⟶ 3,709:
product([[1,2,3], [30], [500,100] ], '%1d %1d %3d' ).
product([[1,2,3], [], [500,100] ], '%1d %1d %3d' ).
product([[1776,1789], [7,12], [4,14,23], [0,1]], '%4d %2d %2d %1d')</langsyntaxhighlight>
{{out}}
<pre>(1 3) (1 4) (2 3) (2 4)
Line 2,593 ⟶ 3,721:
==== 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.
<langsyntaxhighlight lang="perl">$tuples = [ map { [split /:/] } glob '{1,2,3}:{30}:{500,100}' ];
 
for $a (@$tuples) { printf "(%1d %2d %3d) ", @$a; }</langsyntaxhighlight>
{{out}}
<pre>(1 30 500) (1 30 100) (2 30 500) (2 30 100) (3 30 500) (3 30 100)</pre>
Line 2,601 ⟶ 3,729:
==== 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.
<langsyntaxhighlight lang="perl">use ntheory qw/forsetproduct/;
forsetproduct { say "@_" } [1,2,3],[qw/a b c/],[qw/@ $ !/];
 
Line 2,611 ⟶ 3,739:
 
use Algorithm::Loops qw/NestedLoops/;
NestedLoops([[1,2,3],[qw/a b c/],[qw/@ $ !/]], sub { say "@_"; });</langsyntaxhighlight>
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>function cart(sequence s)
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
sequence res = {}
<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>
for n=2 to length(s) do
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
for i=1 to length(s[1]) do
<span style="color: #008080;">for</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
for j=1 to length(s[2]) do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">do</span>
res = append(res,s[1][i]&s[2][j])
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">do</span>
end for
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">][</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]&</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">])</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
if length(s)=2 then exit end if
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
s[1..2] = {res}
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">2</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
res = {}
<span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">res</span><span style="color: #0000FF;">}</span>
end for
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
return res
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
?cart({{1,2},{3,4}})
?cart({{3,4},{1,2}})
<span style="color: #0000FF;">?</span><span style="color: #000000;">cart</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">}})</span>
?cart({{1,2},{}})
<span style="color: #0000FF;">?</span><span style="color: #000000;">cart</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">}})</span>
?cart({{},{1,2}})
<span style="color: #0000FF;">?</span><span style="color: #000000;">cart</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">},{}})</span>
?cart({{1776, 1789},{7, 12},{4, 14, 23},{0, 1}})
<span style="color: #0000FF;">?</span><span style="color: #000000;">cart</span><span style="color: #0000FF;">({{},{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">}})</span>
?cart({{1, 2, 3},{30},{500, 100}})
<span style="color: #0000FF;">?</span><span style="color: #000000;">cart</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">1776</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1789</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">12</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">14</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">23</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">}})</span>
?cart({{1, 2, 3},{},{500, 100}})</lang>
<span style="color: #0000FF;">?</span><span style="color: #000000;">cart</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">30</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">500</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">100</span><span style="color: #0000FF;">}})</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">cart</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">},{},{</span><span style="color: #000000;">500</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">100</span><span style="color: #0000FF;">}})</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 2,649 ⟶ 3,779:
{}
</pre>
 
=={{header|Phixmonti}}==
<langsyntaxhighlight Phixmontilang="phixmonti">include ..\Utilitys.pmt
 
def cart
Line 2,681 ⟶ 3,810:
 
( ( 1 2 ) ( ) ) cart
drop res print nl nl</langsyntaxhighlight>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de 2lists (L1 L2)
(mapcan
'((I)
Line 2,709 ⟶ 3,837:
(cartesian (1 2 3) (30) (500 100)) )
(println
(cartesian (1 2 3) NIL (500 100)) )</langsyntaxhighlight>
 
{{out}}
Line 2,719 ⟶ 3,847:
((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">
<lang Prolog>
product([A|_], Bs, [A, B]) :- member(B, Bs).
product([_|As], Bs, X) :- product(As, Bs, X).
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 2,741 ⟶ 3,868:
=={{header|Python}}==
===Using itertools===
<langsyntaxhighlight lang="python">import itertools
 
def cp(lsts):
Line 2,755 ⟶ 3,882:
print(lists, '=>')
pp(cp(lists), indent=2)
</syntaxhighlight>
</lang>
{{out}}
<pre>[[1, 2], [3, 4]] =>
Line 2,806 ⟶ 3,933:
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):
 
<langsyntaxhighlight lang="python"># ap (<*>) :: [(a -> b)] -> [a] -> [b]
def ap(fs):
return lambda xs: foldl(
lambda a: lambda f: a + foldl(
lambda a: lambda x: a + [f(x)])([])(xs)
)([])(fs)</langsyntaxhighlight>
 
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))</langsyntaxhighlight>
 
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 2,821 ⟶ 3,948:
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:
 
<langsyntaxhighlight lang="python"># nAryCartProd :: [[a], [b], [c] ...] -> [(a, b, c ...)]
def nAryCartProd(xxs):
return foldl1(cartesianProduct)(
xxs
)</langsyntaxhighlight>
 
For example:
 
<langsyntaxhighlight lang="python"># Two lists -> list of tuples
 
 
Line 2,936 ⟶ 4,063:
# TEST ----------------------------------------------------
if __name__ == '__main__':
main()</langsyntaxhighlight>
{{Out}}
<pre>Product of two lists of different types:
Line 2,972 ⟶ 4,099:
[(1, 30, 500), (1, 30, 100), (2, 30, 500), (2, 30, 100), (3, 30, 500), (3, 30, 100)]
[]</pre>
=={{header|Quackery}}==
 
<syntaxhighlight lang="quackery"> [ [] unrot
swap witheach
[ over witheach
[ over nested
swap nested join
nested dip rot join
unrot ]
drop ] drop ] is cartprod ( [ [ --> [ )
 
' [ 1 2 ] ' [ 3 4 ] cartprod echo cr
' [ 3 4 ] ' [ 1 2 ] cartprod echo cr
' [ 1 2 ] ' [ ] cartprod echo cr
' [ ] ' [ 1 2 ] cartprod echo cr</syntaxhighlight>
 
{{out}}
 
<pre>[ [ 1 3 ] [ 1 4 ] [ 2 3 ] [ 2 4 ] ]
[ [ 3 1 ] [ 3 2 ] [ 4 1 ] [ 4 2 ] ]
[ ]
[ ]
</pre>
=={{header|R}}==
 
<syntaxhighlight lang="r">
<lang R>
one_w_many <- function(one, many) lapply(many, function(x) c(one,x))
 
Line 2,993 ⟶ 4,142:
prod = Reduce( '%p%', list(...) )
display_prod( prod ) }
</syntaxhighlight>
</lang>
 
Simple tests:
 
<syntaxhighlight lang="r">
<lang R>
> display_prod( c(1, 2) %p% c(3, 4) )
1, 3
Line 3,010 ⟶ 4,159:
> display_prod( c(3, 4) %p% c() )
>
</syntaxhighlight>
</lang>
 
Tougher tests:
 
<syntaxhighlight lang="r">
<lang 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) )
go( c(1, 2, 3), c(), c(500, 100) )
</syntaxhighlight>
</lang>
 
{{out}}
Line 3,058 ⟶ 4,207:
(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,079 ⟶ 4,227:
(cartesian-product '(1776 1789) '(7 12) '(4 14 23) '(0 1))
(cartesian-product '(1 2 3) '(30) '(500 100))
(cartesian-product '(1 2 3) '() '(500 100))</langsyntaxhighlight>
 
{{out}}
Line 3,109 ⟶ 4,257:
'((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,115 ⟶ 4,262:
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" perl6line># 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,125 ⟶ 4,272:
say [X] (1776, 1789), (7, 12), (4, 14, 23), (0, 1);
say [X] (1, 2, 3), (30), (500, 100);
say [X] (1, 2, 3), (), (500, 100);</langsyntaxhighlight>
{{out}}
<pre>((1 3) (1 4) (2 3) (2 4))
Line 3,134 ⟶ 4,281:
((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.
<langsyntaxhighlight 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,164 ⟶ 4,310:
end /*i*/
say 'Cartesian product of ' space(@.n) " is ───► {"substr($, 2)'}'
end /*n*/ /*stick a fork in it, we're all done. */</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default lists:}}
<pre>
Line 3,175 ⟶ 4,321:
 
===version 2===
<langsyntaxhighlight 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,238 ⟶ 4,384:
End
Say ' '
Return 0</langsyntaxhighlight>
{{out}}
<pre>{1, 2} x {3, 4}
Line 3,294 ⟶ 4,440:
{1, 2, 3} x {} x {500, 100}
{}</pre>
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
# Project : Cartesian product of two or more lists
 
Line 3,311 ⟶ 4,456:
next
see nl
</syntaxhighlight>
</lang>
Output:
<pre>
Line 3,323 ⟶ 4,468:
(4, 1)
(4, 2)
</pre>
=={{header|RPL}}==
≪ → a b
≪ { }
'''IF''' a SIZE b SIZE AND '''THEN'''
1 a SIZE '''FOR''' j
1 b SIZE '''FOR''' k
a j GET b k GET 2 →LIST 1 →LIST +
'''NEXT'''
'''NEXT'''
'''END'''
≫ ≫ '<span style="color:blue">CROIX</span>' STO
{1 2} {3 4} <span style="color:blue">CROIX</span>
{3 4} {1 2} <span style="color:blue">CROIX</span>
{1 2} {} <span style="color:blue">CROIX</span>
{} {1 2} <span style="color:blue">CROIX</span>
{{out}}
<pre>
4: {(1 3) (1 4) (2 3) (2 4)}
3: {(3 1) (3 2) (4 1) (4 2)}
2: {}
1: {}
</pre>
 
=={{header|Ruby}}==
"product" is a method of arrays. It takes one or more arrays as argument and results in the Cartesian product:
<langsyntaxhighlight lang="ruby">p [1, 2].product([3, 4])
p [3, 4].product([1, 2])
p [1, 2].product([])
Line 3,334 ⟶ 4,501:
p [1, 2, 3].product([30], [500, 100])
p [1, 2, 3].product([], [500, 100])
</syntaxhighlight>
</lang>
{{out}}<pre>[[1, 3], [1, 4], [2, 3], [2, 4]]
[[3, 1], [3, 2], [4, 1], [4, 2]]
Line 3,345 ⟶ 4,512:
 
=={{header|Rust}}==
<langsyntaxhighlight lang="rust">fn cartesian_product(lists: &Vec<Vec<u32>>) -> Vec<Vec<u32>> {
let mut res = vec![];
 
Line 3,386 ⟶ 4,553:
}
}
</syntaxhighlight>
</lang>
{{out}}<pre>[1, 2] × [3, 4]
[[1, 3], [1, 4], [2, 3], [2, 4]]
Line 3,408 ⟶ 4,575:
[]
</pre>
 
=={{header|Scala}}==
Function returning the n-ary product of an arbitrary number of lists, each of arbitrary length:
 
<langsyntaxhighlight lang="scala">def cartesianProduct[T](lst: List[T]*): List[List[T]] = {
 
/**
Line 3,441 ⟶ 4,607:
}
}
}</langsyntaxhighlight>
and usage:
<langsyntaxhighlight lang="scala">cartesianProduct(List(1, 2), List(3, 4))
.map(_.mkString("(", ", ", ")")).mkString("{",", ","}")</langsyntaxhighlight>
{{out}}
<pre>{(1, 3), (1, 4), (2, 3), (2, 4)}</pre>
 
<langsyntaxhighlight lang="scala">cartesianProduct(List(3, 4), List(1, 2))
.map(_.mkString("(", ", ", ")")).mkString("{",", ","}")</langsyntaxhighlight>
{{out}}
<pre>{(3, 1), (3, 2), (4, 1), (4, 2)}</pre>
 
<langsyntaxhighlight lang="scala">cartesianProduct(List(1, 2), List.empty)
.map(_.mkString("(", ", ", ")")).mkString("{",", ","}")</langsyntaxhighlight>
{{out}}
<pre>{}</pre>
 
<langsyntaxhighlight lang="scala">cartesianProduct(List.empty, List(1, 2))
.map(_.mkString("(", ", ", ")")).mkString("{",", ","}")</langsyntaxhighlight>
{{out}}
<pre>{}</pre>
 
<langsyntaxhighlight lang="scala">cartesianProduct(List(1776, 1789), List(7, 12), List(4, 14, 23), List(0, 1))
.map(_.mkString("(", ", ", ")")).mkString("{",", ","}")</langsyntaxhighlight>
{{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>
 
<langsyntaxhighlight lang="scala">cartesianProduct(List(1, 2, 3), List(30), List(500, 100))
.map(_.mkString("(", ", ", ")")).mkString("{",", ","}")</langsyntaxhighlight>
{{out}}
<pre>{(1, 30, 500), (1, 30, 100), (2, 30, 500), (2, 30, 100), (3, 30, 500), (3, 30, 100)}</pre>
 
<langsyntaxhighlight lang="scala">cartesianProduct(List(1, 2, 3), List.empty, List(500, 100))
.map(_.mkString("[", ", ", "]")).mkString("\n")</langsyntaxhighlight>
{{out}}
<pre>{}</pre>
 
=={{header|Scheme}}==
<langsyntaxhighlight lang="scheme">
(define cartesian-product (lambda (xs ys)
(if (or (zero? (length xs)) (zero? (length ys)))
Line 3,500 ⟶ 4,665:
> (nary-cartesian-product '((1 2)(a b)(x y)))
((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>
</lang>
 
=={{header|Sidef}}==
In Sidef, the Cartesian product of an arbitrary number of arrays is built-in as ''Array.cartesian()'':
<langsyntaxhighlight lang="ruby">cartesian([[1,2], [3,4], [5,6]]).say
cartesian([[1,2], [3,4], [5,6]], {|*arr| say arr })</langsyntaxhighlight>
 
Alternatively, a simple recursive implementation:
<langsyntaxhighlight lang="ruby">func cartesian_product(*arr) {
 
var c = []
Line 3,527 ⟶ 4,691:
 
return r
}</langsyntaxhighlight>
 
Completing the task:
<langsyntaxhighlight lang="ruby">say cartesian_product([1,2], [3,4])
say cartesian_product([3,4], [1,2])</langsyntaxhighlight>
{{out}}
<pre>
Line 3,538 ⟶ 4,702:
</pre>
The product of an empty list with any other list is empty:
<langsyntaxhighlight lang="ruby">say cartesian_product([1,2], [])
say cartesian_product([], [1,2])</langsyntaxhighlight>
{{out}}
<pre>
Line 3,546 ⟶ 4,710:
</pre>
Extra credit:
<langsyntaxhighlight lang="ruby">cartesian_product([1776, 1789], [7, 12], [4, 14, 23], [0, 1]).each{ .say }</langsyntaxhighlight>
{{out}}
<pre>
Line 3,575 ⟶ 4,739:
</pre>
 
<langsyntaxhighlight lang="ruby">say cartesian_product([1, 2, 3], [30], [500, 100])
say cartesian_product([1, 2, 3], [], [500, 100])</langsyntaxhighlight>
{{out}}
<pre>
Line 3,582 ⟶ 4,746:
[]
</pre>
 
=={{header|SQL}}==
If we create lists as tables with one column, cartesian product is easy.
<langsyntaxhighlight lang="sql">-- set up list 1
create table L1 (value integer);
insert into L1 values (1);
Line 3,594 ⟶ 4,757:
insert into L2 values (4);
-- get the product
select * from L1, L2;</langsyntaxhighlight>
{{out}}
<pre> VALUE VALUE
Line 3,601 ⟶ 4,764:
1 4
2 3
2 4</pre>You should be able to be more explicit should get the same result:<langsyntaxhighlight lang="sql">select * from L1 cross join L2;</langsyntaxhighlight>
Product with an empty list works as expected (using the tables created above):
<langsyntaxhighlight lang="sql">delete from L2;
select * from L1, L2;</langsyntaxhighlight>
{{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):<langsyntaxhighlight lang="sql">insert into L1 values (3);
insert into L2 values (30);
create table L3 (value integer);
Line 3,613 ⟶ 4,776:
insert into L3 values (100);
-- product works the same for as many "lists" as you'd like
select * from L1, L2, L3;</langsyntaxhighlight>
{{out}}
<pre> VALUE VALUE VALUE
Line 3,623 ⟶ 4,786:
2 30 100
3 30 100</pre>
 
=={{header|Standard ML}}==
<langsyntaxhighlight lang="sml">fun prodList (nil, _) = nil
| prodList ((x::xs), ys) = map (fn y => (x,y)) ys @ prodList (xs, ys)
 
fun naryProdList zs = foldl (fn (xs, ys) => map op:: (prodList (xs, ys))) [[]] (rev zs)</langsyntaxhighlight>
 
{{out}}
Line 3,652 ⟶ 4,814:
- 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.
 
<langsyntaxhighlight lang="stata">. list
 
+-------+
Line 3,676 ⟶ 4,837:
3. | 2 3 1 |
4. | 2 4 0 |
+-----------------+</langsyntaxhighlight>
 
The other way around:
 
<langsyntaxhighlight lang="stata">. list
 
+-------+
Line 3,699 ⟶ 4,860:
3. | 4 1 1 |
4. | 4 2 0 |
+-----------------+</langsyntaxhighlight>
 
Note, however, that this is not equivalent to a cartesian product when one of the variables is "empty" (that is, only contains missing values).
 
<langsyntaxhighlight lang="stata">. list
 
+-------+
Line 3,720 ⟶ 4,881:
1. | 1 . 0 |
2. | 2 . 0 |
+-----------------+</langsyntaxhighlight>
 
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.
 
<langsyntaxhighlight lang="stata">. list
 
+-----------+
Line 3,779 ⟶ 4,940:
|---------------------|
6. | 3 5 6 1 |
+---------------------+</langsyntaxhighlight>
 
=={{header|Swift}}==
 
{{trans|Scala}}
 
<langsyntaxhighlight lang="swift">func + <T>(el: T, arr: [T]) -> [T] {
var ret = arr
 
Line 3,827 ⟶ 4,987:
print(cartesianProduct([1776, 1789], [7, 12], [4, 14, 23], [0, 1]))
print(cartesianProduct([1, 2, 3], [30], [500, 100]))
print(cartesianProduct([1, 2, 3], [], [500, 100])</langsyntaxhighlight>
 
{{out}}
Line 3,837 ⟶ 4,997:
[[1, 30, 500], [1, 30, 100], [2, 30, 500], [2, 30, 100], [3, 30, 500], [3, 30, 100]]
[]</pre>
 
=={{header|Tailspin}}==
<langsyntaxhighlight lang="tailspin">
'{1,2}x{3,4} = $:[by [1,2]..., by [3,4]...];
' -> !OUT::write
Line 3,864 ⟶ 5,023:
'year {1776, 1789} × month {7, 12} × day {4, 14, 23} = $:{by [1776, 1789]... -> (year:$), by [7, 12]... -> (month:$), by [4, 14, 23]... -> (day:$)};
' -> !OUT::write
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 3,876 ⟶ 5,035:
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}}==
<langsyntaxhighlight lang="tcl">
proc cartesianProduct {l1 l2} {
set result {}
Line 3,914 ⟶ 5,072:
puts "result: [cartesianNaryProduct {{1 2 3} {} {500 100}}]"
 
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 3,927 ⟶ 5,085:
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:
 
$ printf '%s' "("{1,2},{3,4}")"; printf '\n'
(1,3)(1,4)(2,3)(2,4)
$ printf '%s' "("{3,4},{1,2}")"; printf '\n'
(3,1)(3,2)(4,1)(4,2)
 
More than two lists is not a problem:
$ printf '%s\n' "("{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)
$ printf '%s\n' "("{1,2,3},30,{500,100}")"
(1,30,500)
(1,30,100)
(2,30,500)
(2,30,100)
(3,30,500)
(3,30,100)
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<langsyntaxhighlight lang="vbnet">Imports System.Runtime.CompilerServices
 
Module Module1
Line 3,966 ⟶ 5,164:
End Sub
 
End Module</langsyntaxhighlight>
{{out}}
<pre>{(1, 3), (1, 4), (2, 3), (2, 4)}
Line 3,975 ⟶ 5,173:
{(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}}
<langsyntaxhighlight ecmascriptlang="wren">import "./seq" for Lst
 
var prod2 = Fn.new { |l1, l2|
Line 4,011 ⟶ 5,208:
printProdN.call([ [1, 2, 3], [30], [500, 100] ])
printProdN.call([ [1, 2, 3], [], [500, 100] ])
printProdN.call([ [1, 2, 3], [30], ["a", "b"] ])</langsyntaxhighlight>
 
{{out}}
Line 4,078 ⟶ 5,275:
Cartesian product is build into iterators or can be done with nested
loops.
<langsyntaxhighlight 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,084 ⟶ 5,281:
 
zkl: Walker.cproduct(List(3,4),List(1,2)).walk().println();
L(L(3,1),L(3,2),L(4,1),L(4,2))</langsyntaxhighlight>
 
The walk method will throw an error if used on an empty iterator but the pump
method doesn't.
<langsyntaxhighlight lang="zkl">zkl: Walker.cproduct(List(3,4),List).walk().println();
Exception thrown: TheEnd(Ain't no more)
 
Line 4,094 ⟶ 5,291:
L()
zkl: Walker.cproduct(List,List(3,4)).pump(List).println();
L()</langsyntaxhighlight>
<langsyntaxhighlight 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),...)
 
Line 4,102 ⟶ 5,299:
 
zkl: Walker.cproduct(L(1,2,3),List,L(500,100)).pump(List).println();
L()</langsyntaxhighlight>
885

edits