Cartesian product of a list with itself n times

10

1

When given a a list of values and a positive integer n, your code should output the cartesian product of the list with itself n times.

For example, in pseudocode your function could be similar to:

for x1 in list:
    for x2 in list:
        for x3 in list:
            ...
            for xn in list:
                print x1, x2, x3, ... , xn

Example:

repeated_cart([1,2,3], 3)

1 1 1  
1 1 2  
1 1 3  
1 2 1  
1 2 2  
1 2 3  
1 3 1  
1 3 2  
1 3 3  
2 1 1  
2 1 2  
2 1 3  
2 2 1  
2 2 2  
2 2 3  
2 3 1  
2 3 2  
2 3 3  
3 1 1  
3 1 2  
3 1 3  
3 2 1  
3 2 2  
3 2 3  
3 3 1  
3 3 2  
3 3 3

Built in functions (or functions from imported libraries) that compute the Cartesian product (or power) are not allowed due to the resulting code being somewhat boring.

Inputs and outputs should be delimited but can be taken in any reasonable method.

the order the output is given does not matter but duplicates are not allowed.

This is my first time posting a question, so if I did anything horribly wrong, please tell me.

JoshM

Posted 2018-05-29T18:18:22.530

Reputation: 379

5

Welcome to PPCG! Nothing horribly wrong, but take some time to look at this meta post and answers.Things to avoid when writing challenges

– JayCe – 2018-05-29T18:37:21.013

4

and to follow on @JayCe 's point, you could (should) post in The Sandbox to get feedback before posting a question :-)

– Giuseppe – 2018-05-29T18:40:53.833

@Giuseppe Ok, I'll do that from now on, thanks :) – JoshM – 2018-05-29T18:47:37.627

1

Borderline dupe of https://codegolf.stackexchange.com/q/125104/194

– Peter Taylor – 2018-05-29T19:14:26.400

@JoshuaMartin can we use builtins that return all n-tuples over 0...m-1? – ngn – 2018-05-29T19:18:53.263

@ngn sure but you'll need to make sure the output is in the right order – JoshM – 2018-05-29T19:25:27.150

The Cartesian product is an operation on sets. Do you allow sets for I/O rather than lists? – Jakob – 2018-05-29T23:47:50.010

1@Jakob sets should be fine – JoshM – 2018-05-30T01:24:34.680

My R program has the output in a different order than your example. You say "make sure the output is in the right order" but what does that mean? Could you put that in the question body so it's clear for future answers? – Giuseppe – 2018-05-30T17:17:14.490

@Giuseppe sorry, I realise now that order does not matter – JoshM – 2018-05-30T22:26:59.197

Answers

8

Haskell, 21 bytes

l#n=mapM(\_->l)[1..n]

Try it online!

Laikoni

Posted 2018-05-29T18:18:22.530

Reputation: 23 676

6

Common Lisp, 146 bytes

(defun f(l n)(if(< n 2)(loop for x in l collect(list x))(loop for a in l nconc(loop for b in(f l(1- n))collect(cons a b)))))(princ(f(read)(read)))

Try it online!

ungolfed

(defun nloops (lst n)
  (if (< n 1)
      '(())
      (if (< n 2)
          (loop for x in lst collect (list x))
          (loop for a in lst
                nconc (loop for b in (nloops lst (1- n))
                            collect (cons a b))))))

JoshM

Posted 2018-05-29T18:18:22.530

Reputation: 379

2typically we suggest waiting for other submissions before posting one of your own :-) – Giuseppe – 2018-05-29T18:33:51.317

1@Giuseppe Ok, thanks for the advice :) – JoshM – 2018-05-29T18:47:09.453

I should say, it's technically not required anywhere but you'll accumulate random downvotes (as you already have) which is unfortunate considering this is a perfectly reasonable answer. – Giuseppe – 2018-05-29T18:50:38.880

@Giuseppe i'll keep that in mind. – JoshM – 2018-05-29T20:46:23.537

1you don't have to have the print statement in the submission, since a function is allowed – ASCII-only – 2018-06-01T11:07:51.737

1

so: 96

– ASCII-only – 2018-06-01T11:22:18.730

190 – ASCII-only – 2018-06-01T11:26:22.660

6

R, 41 bytes

function(l,n)unique(t(combn(rep(l,n),n)))

Try it online!

combn is definitely not a cartesian product built-in, as it computes all n-combinations of its input.

R, 40 bytes

function(l,n)expand.grid(rep(list(l),n))

Try it online!

expand.grid is probably a cartesian product built-in.

Giuseppe

Posted 2018-05-29T18:18:22.530

Reputation: 21 077

Looks like the order of permutations in your main submission is wrong. – Kirill L. – 2018-05-30T09:01:46.777

@KirillL. is there a particular reason the order is important? I interpreted the output spec as being flexible enough to allow them in any order. – Giuseppe – 2018-05-30T16:34:36.037

there is OP's comment "make sure the output is in the right order", I presumed "right" means same as in example. – Kirill L. – 2018-05-30T16:46:48.427

@KirillL. Ah. Didn't see that; it's not in the body of the question so I did not know it existed! I'll ask that it gets put there for clarification. – Giuseppe – 2018-05-30T17:12:04.283

4

Perl 6, 16 bytes

{[X,] $^a xx$^b}

Try it

Expnded:

{  # bare block lambda with placeholder parameters $a and $b

  [X,]         #reduce using Cross meta op combined with comma op

    $^a xx $^b # list repeat $a, by $b times
}

Brad Gilbert b2gills

Posted 2018-05-29T18:18:22.530

Reputation: 12 713

3

APL (Dyalog Classic), 18 12 bytes

{⍺[↑,⍳⍵⍴≢⍺]}

Try it online!

-6 bytes thanks to @ngn !

Zacharý

Posted 2018-05-29T18:18:22.530

Reputation: 5 710

you can use with a vector argument to generate indices and then ⍺[ ] to get the corresponding values

– ngn – 2018-05-29T19:35:06.073

I got a RANK ERROR when I tried to do that. – Zacharý – 2018-05-29T19:40:09.547

⍺[↑,⍳⍵⍴≢⍺] – ngn – 2018-05-29T19:48:35.263

the only catch is with ⍵=1, in that case ⍳ returns a plain vector, not a vector of nested length-1 vectors as one would expect; it's one of those bugs that never get fixed, for backwards-compatibility reasons – ngn – 2018-05-29T19:56:52.767

3

K (ngn/k), 10 bytes

{x@+!y##x}

Try it online!

{ } is a function with arguments x and y

#x the length of x

y##x the length of x repeated y times

!y##x all length-y tuples over 0,1,...,length(x)-1 as a transposed matrix

+ transpose

x@ elements of x at those indices

ngn

Posted 2018-05-29T18:18:22.530

Reputation: 11 449

3

Python 2, 69 58 bytes

f=lambda a,n:n and[v+[i]for v in f(a,n-1)for i in a]or[[]]

Try it online!

Takes a list a and an integer n; returns a list of lists.

Chas Brown

Posted 2018-05-29T18:18:22.530

Reputation: 8 959

3

Perl 5, 33 bytes

say for glob(join',',("{$_}")x<>)

Try it online!

Xcali

Posted 2018-05-29T18:18:22.530

Reputation: 7 671

Nice! So many answers have been able to utilise this lately! You can save 2 bytes with a bit of juggling: Try it online!

– Dom Hastings – 2018-05-29T20:24:49.270

3

Ruby, 53 bytes

f=->l,n{n<2?l:l.flat_map{|i|f[l,n-1].map{|j|[i,*j]}}}

Try it online!

Recursive approach, not so short, but guaranteed to be free of any built-ins.

It's tempting to use permutation methods, but this probably doesn't count, and the docs actually state no guarantees of the order correctness, although seems to work in practice:

Ruby, 35 bytes

->l,n{[*l.repeated_permutation(n)]}

Try it online!

Kirill L.

Posted 2018-05-29T18:18:22.530

Reputation: 6 693

2

Jelly, 11 9 7 bytes

³;þẎƊ’¡

Try it online!

Explanation

³;þẎƊ’¡
³;þẎ    **Implements** the cartesian product of a value with the input
    Ɗ   Groups those together
     ’¡ Repeat (n-1) times

Zacharý

Posted 2018-05-29T18:18:22.530

Reputation: 5 710

Look at OP's comment :p – Zacharý – 2018-05-29T18:43:06.117

My comment to which I brought it up is: "I'm also assuming builtins for the entire challenge are also disalowed," so I just assumed this is okay. – Zacharý – 2018-05-29T18:45:40.013

Well, let's wait for OP then – Zacharý – 2018-05-29T18:49:33.423

@Zacharý sorry, the cartesian power function isn't allowed – JoshM – 2018-05-29T19:03:36.743

There, I fixed it to not use the cartesian power built-in – Zacharý – 2018-05-29T19:04:26.727

Is þ allowed if it is a cartesian product quick? If it's not €Ɱ works – dylnan – 2018-05-29T19:35:06.543

Outer product – Zacharý – 2018-05-29T19:35:57.243

The portion that's doing the work is . – Zacharý – 2018-05-29T19:36:46.910

Technically ×þ is an outer product. The outer product is just the cartesian product with the resulting pairs multiplied, so þ is better described as a cartesian product imo. – dylnan – 2018-05-29T19:39:06.473

It's called table. And it can be done without generating the cartesian product. – Zacharý – 2018-05-29T19:42:05.443

[[dyadic_link(link, (u, v)) for u in iterable(x, make_range = True)] for v in iterable(y, make_range = True)], that code is the relevant Jelly code. Nowhere does it calculate the cartesian product – Zacharý – 2018-05-29T19:43:24.380

3I don't know, two nested for loops like that is basically the definition of a cartesian product. I'm not saying you should change it though, I just think banning the built-in in this challenge is kind of unclear. – dylnan – 2018-05-29T19:47:21.767

Let us continue this discussion in chat.

– Zacharý – 2018-05-29T19:51:27.943

2

Prolog (SWI), 72 bytes

R-1-R.
L-N-R:-O is N-1,L-O-M,findall([H|T],(member(H,L),member(T,M)),R).

Try it online!

ASCII-only

Posted 2018-05-29T18:18:22.530

Reputation: 4 687

2

Java 10, 19 + 135 = 154 bytes

import java.util.*;

List<List>f(Set l,int n){var o=new Stack();if(n<1)o.add(new Stack());else for(var t:l)for(var i:f(l,n-1)){i.add(t);o.add(i);}return o;}

Try It Online

Ungolfed

List<List> f(Set l, int n) {
    var o = new Stack();
    if (n < 1)
        o.add(new Stack());
    else
        for (var t : l)
            for (var i : f(l, n - 1)) {
                i.add(t);
                o.add(i);
            }
    return o;
}

Acknowledgments

  • port to Java 10 thanks to Kevin Cruijssen

Jakob

Posted 2018-05-29T18:18:22.530

Reputation: 2 428

If you use Java 10 instead of 8, you can change Object and List in the for-each loops to var for -4 bytes. In addition, you can then change Set<List>f to List<List>f and Set o=new HashSet(); to var o=new Stack(); for an additional -1 byte. Try it online.

– Kevin Cruijssen – 2018-05-30T07:08:05.343

Hmm. is leaving out types for lambdas no longer valid – ASCII-only – 2018-05-31T12:37:34.043

@ASCII-only No, untyped lambdas are allowed. I couldn't use a lambda here because the solution uses recursion. – Jakob – 2018-05-31T19:12:14.980

@Jakob ah, that's right >_> – ASCII-only – 2018-06-01T00:58:01.477

2

Racket, 92 bytes

(define(f l n)(if(> n 0)(apply append(map(λ(r)(map(λ(e)(cons e r))l))(f l(- n 1))))'(())))

Try It Online

Ungolfed

(define (f l n)
    (if (> n 0)
        (apply append
            (map
                (λ (r)
                    (map (λ (e) (cons e r)) l)
                )
                (f l (- n 1))
            )
        )
        '(())
    )
)

Jakob

Posted 2018-05-29T18:18:22.530

Reputation: 2 428

2

Pure Bash (no external utilities), 57

printf -vn %0$1d
a=${n//0/{$2\}}
eval echo ${a//\}{/\},{}

Input is given as command-line parameters; 1st is n, 2nd is a comma-separated list.

printf -vn %0$1d         ;# Create a string of n "0"s in the variable v
a=${n//0/{$2\}}          ;# Replace each "0" with "{a,b,...m}"
eval echo ${a//\}{/\},{} ;# Replace each "}{" with "},{" and evaluate the resulting brace expansion

Try it online!

Digital Trauma

Posted 2018-05-29T18:18:22.530

Reputation: 64 644

2

Oracle SQL, 177 bytes

Create a collection type (31 bytes):

CREATE TYPE t IS TABLE OF INT;

Then use the query (146 bytes):

WITH n(a,b,c)AS(SELECT a,b,t()FROM i UNION ALL SELECT a,b-1,c MULTISET UNION t(COLUMN_VALUE)FROM n,TABLE(n.a)WHERE b>=0)SELECT c FROM n WHERE b=0

Assuming that the input parameters are in the table i with columns a and b:

CREATE TABLE i (a t,b INT) NESTED TABLE a STORE AS t_a;
INSERT INTO i VALUES ( t(1,2,3), 3 );

SQL Fiddle

Results:

|     C |
|-------|
| 1,1,1 |
| 1,1,2 |
| 1,1,3 |
| 1,2,1 |
| 1,2,2 |
| 1,2,3 |
| 1,3,1 |
| 1,3,2 |
| 1,3,3 |
| 2,1,1 |
| 2,1,2 |
| 2,1,3 |
| 2,2,1 |
| 2,2,2 |
| 2,2,3 |
| 2,3,1 |
| 2,3,2 |
| 2,3,3 |
| 3,1,1 |
| 3,1,2 |
| 3,1,3 |
| 3,2,1 |
| 3,2,2 |
| 3,2,3 |
| 3,3,1 |
| 3,3,2 |
| 3,3,3 |

MT0

Posted 2018-05-29T18:18:22.530

Reputation: 3 373

1

Bash, 61 bytes

N=$1
shift
IFS=,
printf echo\\t%${N}s ""|sed "s/ /{$*},/g"|sh

Try it online! I found repeating strings and joining lists with commas surprisingly hard to do in bash.

Neil

Posted 2018-05-29T18:18:22.530

Reputation: 95 035

1

Javascript (Node), 75 bytes

c=(m,n,a,i)=>a.length-n?m.map((_,j)=>c(m,n,[...a,m[j]],i+1)):console.log(a)

Recursive function which outputs the list to the console. Where a is an empty array and i is 0 (not sure if this still qualifies):

c([1,2,3], 3, [], 0);

Try it online!

Asleepace

Posted 2018-05-29T18:18:22.530

Reputation: 311

1I think you would have to do (m,n,a=[],i=0)=> – Artyer – 2018-05-30T08:51:53.503

1

JavaScript (SpiderMonkey), 52 bytes

c=>g=(n,...l)=>n?c.map(w=>g(n-1,...l,w)):print(...l)

Try it online!

tsh

Posted 2018-05-29T18:18:22.530

Reputation: 13 072

1

J, 17 bytes

]{~(##)#:#@]i.@^[

How it works?

I enumerate all the n-digit numbers in a number system with base the length of the list.

            i.         - creates a list from zero to (not including)
         #@]           - the length of the list 
              @^       - to the power of
                [      - n (left argument)
   (##)                - creates a list of n times the length of the list (for the bases)
       #:              - converts all the numbers into lists of digits in the new base
]{~                    - use the digits as indices into the list

Try it online!

Galen Ivanov

Posted 2018-05-29T18:18:22.530

Reputation: 13 815

1

CJam, 26 bytes

q~(_"m*:e_"*\'_*@\~W$~:p];

Try it online!

If only CJam had one character commands for cartesian product and flattening.

maxb

Posted 2018-05-29T18:18:22.530

Reputation: 5 754

0

Octave, 38 bytes

@(x,n)x(dec2base(0:n^numel(x)-1,n)-47)

Anonymous function that takes a row vector of values and an integer.

Try it online!

Luis Mendo

Posted 2018-05-29T18:18:22.530

Reputation: 87 464

0

Pari/GP, 46 bytes

(l,n)->matrix(#l^n,n,i,j,l[i--\#l^(n-j)%#l+1])

Try it online!

alephalpha

Posted 2018-05-29T18:18:22.530

Reputation: 23 988