17
\$\begingroup\$

Task

Given two lists of characters, output their Cartesian product, i.e. the list of pairings of each letter from the first list with each letter from the second list.

Example

"123456" and "abcd" give:

[["1","a"],["1","b"],["1","c"],["1","d"],["2","a"],["2","b"],["2","c"],["2","d"],["3","a"],["3","b"],["3","c"],["3","d"],["4","a"],["4","b"],["4","c"],["4","d"],["5","a"],["5","b"],["5","c"],["5","d"],["6","a"],["6","b"],["6","c"],["6","d"]]

Input

Two lists of characters or strings. The characters used will be alphanumeric a-z, A-Z, 0-9 and a character can occur both multiple times and in both inputs at the same time.

Output

The Cartesian product of the input lists. That is, a list of each possible ordered pair of a character from the first list and a character from the second list. Each pair is a list or string or similar of two characters, or of two length-one strings. The output's length will be equal to the product of the lengths of the inputs.

The pairs must be listed in order; first listing the first character of the first list with the first of the second list, followed by all the pairings of the first character of the first list. The last pair consists of the last character of the first list together with the last character of the second list.

The output must be a flat list of pairs; not a 2D matrix where pairs are grouped by their first or second element.

Test cases

inputs               output

"123456", "abcd"     [["1","a"],["1","b"],["1","c"],["1","d"],["2","a"],["2","b"],["2","c"],["2","d"],["3","a"],["3","b"],["3","c"],["3","d"],["4","a"],["4","b"],["4","c"],["4","d"],["5","a"],["5","b"],["5","c"],["5","d"],["6","a"],["6","b"],["6","c"],["6","d"]]
"abc", "123"         [["a","1"],["a","2"],["a","3"],["b","1"],["b","2"],["b","3"],["c","1"],["c","2"],["c","3"]]
"aa", "aba"          [["a","a"],["a","b"],["a","a"],["a","a"],["a","b"],["a","a"]]
\$\endgroup\$
10
  • \$\begingroup\$ @Adám Changed. I'm having trouble though wording that repeated characters in an input string can and should cause repeated pairs in the output (assuming that's how interpret it). \$\endgroup\$
    – xnor
    Jun 8, 2017 at 0:25
  • \$\begingroup\$ @xnor maybe easier if the order of pairs is fixed? \$\endgroup\$
    – Adám
    Jun 8, 2017 at 0:28
  • \$\begingroup\$ Why does the title say "list" yet the body say "list of characters"? \$\endgroup\$
    – Leaky Nun
    Jun 8, 2017 at 7:56
  • \$\begingroup\$ Just to be sure: is ["1a", "1b", "1c", "2a", "2b", "2c", "3a", "3b", "3c"] a valid output format? \$\endgroup\$
    – Shaggy
    Jun 8, 2017 at 16:22
  • 2
    \$\begingroup\$ You tagged this as code-golf therefore shortest answer wins. In the event of a tie, the first answer to reach that score is usually the winner (currently this one). Give it another few days, at least, before accepting an answer, though, if at all. And see here for guidelines on answering your own question. \$\endgroup\$
    – Shaggy
    Jun 9, 2017 at 10:52

51 Answers 51

1
2
1
\$\begingroup\$

Charcoal, 8 7 bytes

FθEη⁺ικ

Try it online! Link is to verbose version of code. Explanation: The variables θ and η implicitly refer to the two input strings. The command loops over each character of the first input, while the command maps over each character of the second input concatenating the loop variable ι and the map variable κ, the result of which is implicitly printed on separate lines.

\$\endgroup\$
2
  • \$\begingroup\$ This seems to be 19 bytes. \$\endgroup\$ Jun 9, 2017 at 16:44
  • 1
    \$\begingroup\$ @CalculatorFeline Charcoal has its own code page. \$\endgroup\$
    – Neil
    Jun 9, 2017 at 17:03
1
\$\begingroup\$

R, 29 bytes

function(x,y)outer(x,y,paste)

Try it online!

Note that R matrix are filled by column, so the result is in the order dictated by the spec.

If allowed to have factors for input and output, there is a built-in... but one needs to extract the resulting levels from the factor so in the end it would be more than 29 bytes.

R, 11 bytes

interaction

Try it online!

\$\endgroup\$
1
\$\begingroup\$

GolfScript, 21 bytes

~\:a;{a{[.;1$]}%\;}%`

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Google Sheets, 101

Inputs A1, B1.

=ArrayFormula(REGEXEXTRACT(Flatten(MID(A1,SEQUENCE(LEN(A1)),1)&MID(B1,SEQUENCE(1,LEN(B1)),1)),"(.)(.)

How it Works

  • Turn string into character array. The first is vertical, the second is horizontal because of how we call SEQUENCE.
  • Concatenate every permutation of one letter from each string. (Because one is vertical and the other is horizontal.
  • Flatten into array
  • Extract first and second character by Regex
  • I considered delimiting by commas and splitting, but that would have required more work if the first string had a comma (or whatever delimiting character).

Notes

  • Flatten is an undocumented function that turns any range into a column array.
\$\endgroup\$
1
\$\begingroup\$

Scala, 24 bytes

for(x<-_;y<-_)yield(x,y)

Try it online!

I love for comprehensions.

\$\endgroup\$
1
\$\begingroup\$

Add++, 8 bytes

L*,€€+BF

Try it online!

How it works

L*,		; Create an anonymous function that returns the entire stack
		; Example inputs: 	"abc" "123"
	€	; Over each char:	["1" "abc"]
	 €	;   Over each char:	["1" "a"]
	  +	;     Concatenate	"a1"
		;   This returns	["a1" "a2" "a3"]
		; This returns		[[["a1" "a2" "a3"] ["b1" "b2" "b3"] ["c1" "c2" "c3"]]]
	BF	; Flatten		["a1" "a2" "a3" "b1" "b2" "b3" "c1" "c2" "c3"]
\$\endgroup\$
1
\$\begingroup\$

Vyxal, 1 byte

Π

Try it Online!

Vyxal's built ins are fun!

\$\endgroup\$
1
\$\begingroup\$

JavaScript (ES6), 35 bytes

a=>b=>a.flatMap(x=>b.map(y=>[x,y]))

f=
a=>b=>a.flatMap(x=>b.map(y=>[x,y]))

document.write(`<pre style="font-size: 1rem">${[
  "f([1, 2, 3])(['a', 'b', 'c']) ",
  "f([2, 4, 6, 8])([1, 3, 5, 7]) ",
  "f(['A', 'B'])(['c', 'd', 'e'])",
].map(test => `${test} &rarr; ${JSON.stringify(eval(test))}`).join("\n")}</pre>`)

\$\endgroup\$
1
\$\begingroup\$

Thunno 2, 1 byte

Built-in. Takes input in reversed order.

Screenshot

Screenshot

\$\endgroup\$
1
\$\begingroup\$

TypeScript Type System, 111 bytes

type X<A,B>=A extends[infer F,...infer R]?[...B extends[any,...infer V]?[[F,B[0]],...X<[F],V>]:[],...X<R,B>]:[]

Test it at the TypeScript playground

My old, more intuitive answer is unfortunately invalid due to the challenge requiring an array of tuples rather than an array of arrays of tuples. This complicated mess, on the other hand, seems to be shorter than using the old version and defining a flatten-type.

type X<A, B> = A extends [ // generic type X takes tuples A and B
  infer F,                 // from A, get first (F)
  ...infer R               // and rest (R)
]
  ? [                                // push:
      ...B extends [any, ...infer V] //   get first and rest (V) from B
        ? [                          //   push:
            [F, B[0]],               //     [ F, B[0] ]
            ...X<[F], V>             //     recurse with [F], V
          ]
        : [],
      ...X<R, B>                     //   recurse with R, B
    ]
  : [];

TypeScript Type System, 57 bytes

This is technically invalid for this specific challenge, but I'm leaving it here since it is more practical for other challenges where cartesian product is used.

type P<A,B>={[I in keyof A]:{[J in keyof B]:[A[I],B[J]]}}

Test it at the TypeScript playground

Pretty simple but I'll leave an explanation anyway for those who don't know any TypeScript:

type P<A, B> = {                 // generic type P takes tuple types A and B
  [I in keyof A]: {              //   for index i in A:
    [J in keyof B]: [A[I], B[J]] //     for index j in B: tuple [A[i], B[j]]
  }                              //   end
}                                // end
\$\endgroup\$
1
\$\begingroup\$

Julia, 21 bytes

a^b=permutedims(a).*b

Attempt This Online!

Takes input as character arrays, returns length-2 strings. Frustratingly, one-byte ' operator doesn't work with text, so we have to permutedims instead. Still a few bytes shorter than a nested for loop.

While this technically returns a 2D matrix, which the OP doesn't want, it does support 1D-indexing (as demonstrated in test cases on ATO), and so is perfectly usable as a flat list. However, this requirement probably invalidates the built-in answer, as Julia flattens the Matrix in column-major order, giving a different result sequence:

Julia, 17 bytes

Iterators.product

Attempt This Online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 15 bytes: a^b=[a...;;].*b (needs julia 1.7+) \$\endgroup\$
    – MarcMush
    May 31 at 15:37
1
\$\begingroup\$

><> (Fish), 92 bytes

fi:?v~:f(?v1-00.
-10.\i{:{:}$}$p1
1~v?gf:11~/.27oa$<v!?ge:+1$
  \:fgo$:ego$1+ $/;
          

Try it

Each list should be prefixed by it's length

enter image description here

\$\endgroup\$
1
\$\begingroup\$

Nekomata, 2 bytes

ᵐ~

Attempt This Online!

ᵐ   Map
 ~  Any of

A port of @Fatalize's Brachylog answer.

\$\endgroup\$
0
\$\begingroup\$

Jq 1.5, 29 bytes

map(split(""))|[combinations]

Uses combinations builtin.

Sample Run

$ jq -Mc  'map(split(""))|[combinations]' <<< '["123456","abcd"]'
[["1","a"],["1","b"],["1","c"],["1","d"],["2","a"],["2","b"],["2","c"],["2","d"],["3","a"],["3","b"],["3","c"],["3","d"],["4","a"],["4","b"],["4","c"],["4","d"],["5","a"],["5","b"],["5","c"],["5","d"],["6","a"],["6","b"],["6","c"],["6","d"]]

$ echo -n 'map(split(""))|[combinations]' | wc -c
  29
\$\endgroup\$
0
\$\begingroup\$

Axiom, 55 bytes

f(a,b)==concat[[[a.x,b.y]for y in 1..#b]for x in 1..#a]

some results

(15) -> f("123456","abcd")
   (15)
   [[1,a], [1,b], [1,c], [1,d], [2,a], [2,b], [2,c], [2,d], [3,a], [3,b],
    [3,c], [3,d], [4,a], [4,b], [4,c], [4,d], [5,a], [5,b], [5,c], [5,d],
    [6,a], [6,b], [6,c], [6,d]]
                                                Type: List List Character
(16) -> f("abc","123")
   (16)  [[a,1],[a,2],[a,3],[b,1],[b,2],[b,3],[c,1],[c,2],[c,3]]
                                                Type: List List Character
(17) -> f("aa","aba")
   (17)  [[a,a],[a,b],[a,a],[a,a],[a,b],[a,a]]
                                                Type: List List Character
\$\endgroup\$
0
\$\begingroup\$

APL NARS 8 chars

{,⍺∘.,⍵}

Copy from https://codegolf.stackexchange.com/a/125115/58988 test

f←{,⍺∘.,⍵}
'123456' f 'abcd'
 1a 1b 1c 1d 2a 2b 2c 2d 3a 3b 3c 3d 4a 4b 4c 4d 5a 5b 5c 5d 6a 6b 6c 6d 
\$\endgroup\$
0
\$\begingroup\$

Prolog (SWI), 48 bytes

L-R:-findall([A,B],(member(A,L),member(B,L)),R).

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Pyt, 1 byte

×

Try it online!

Gotta love built-ins.

\$\endgroup\$
0
\$\begingroup\$

Thunno, \$ 2 \log_{256}(96) \approx \$ 1.65 bytes

Z!

Attempt This Online!

Thunno, \$ 2 \log_{256}(96) \approx \$ 1.65 bytes

zS

Attempt This Online!

Built-in solutions.

\$\endgroup\$
0
\$\begingroup\$

Scala, 45 bytes

Golfed version. Try it online!

(a:String,b:String)=>for{x<-a;y<-b}yield(x,y)
\$\endgroup\$
0
\$\begingroup\$

awk, 101 bytes

it's verbose but doesn't involve cryptic BS

echo '123456 abcd' | 

awk 'function ___(_,__) { gsub(".","\\&& ",__)gsub(".",__,_); return _ 
     }$++NF = ___($++_, $++_)'

123456 abcd 1a 1b 1c 1d 2a 2b 2c 2d 3a 3b 3c 3d 4a 4b 4c 4d 5a 5b 5c 5d 6a 6b 6c 6d 
\$\endgroup\$
0
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.