Cartesian product of two or more lists: Difference between revisions

add freebasic
(Add APL)
(add freebasic)
Line 873:
IN: scratchpad { } { 1 2 } cartesian-product .
{ }</lang>
 
=={{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.
 
<lang>#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, C, D, E, F, G, H, J, 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</lang>
{{out}}<pre>#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, C, 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</pre>
 
=={{header|Fōrmulæ}}==
781

edits