# All non-ordered pairs between the elements of an array

Return an array with all possible pairs between the elements of an array.

Example

From a=["a", "b", "c", "d"]; return b=[["a","b"],["a","c"],["a","d"],["b","c"],["b","d"],["c","d"]].

Pairs can be in any order as long as all possible combinations are included and obviously ["b","d"] is the same to ["d","b"].

Input

Array of unique string elements composed of chars from the class [a-z].

Output

2d array containing all the possible pairs of input array's elements.

Test Cases

input=["a","b","c"];
//output=[["a","b"],["a","c"],["b","c"]]

input=["a","b","c","d","e"];
//output=[["a","b"],["a","c"],["a","d"],["a","e"],["b","c"],["b","d"],["b","e"],["c","d"],["c","e"],["d","e"]]


Note: I could not find a duplicate to this challenge. If there is one, alert me with a comment to drop question.

• I'm not clear on what happens when input values repeat or are not in sorted order. Some more general test cases would help there.
– xnor
Jun 19, 2017 at 20:05
• @Adám Not a dupe, that involves having 2 lists. Jun 19, 2017 at 20:10
• This problem excludes pairing an element with itself, soeven more nonduplicate. Jun 19, 2017 at 20:10
• @xnor havent thought about repeating values because my original problem at work had to do with a unique set of individuals. I guess I should add uniqueness as a condition? Jun 19, 2017 at 20:57
• @alexandros84 Uniqueness would be fine. What should ["c","b","a"] return?
– xnor
Jun 19, 2017 at 21:00

f(a:b)=map((,)a)b++f b
f _=[]


Try it online! Example usage: f ["a","b","c"] yields [("a","b"),("a","c"),("b","c")].

With the flag -XTupleSections this can be shortened to 27 bytes, however the flag would need to be counted:

f(a:b)=map(a,)b++f b
f _=[]


Try it online!

• I think you can save one byte by modifying the be case to f l=l. Jun 19, 2017 at 21:31
• @Kritzefitz I'm afraid this won't work as the two empty lists have a different type, so Haskell's type checker will complain. Jun 19, 2017 at 21:34
• Good point. I Didn't think of that. Jun 19, 2017 at 21:39

# Mathematica, 14 bytes

#~Subsets~{2}&


input

[{"a", "b", "c"}]

• I was going to do that :( Jun 19, 2017 at 20:10

f l=[(x,y)|x<-l,y<-l,x<y]


Try it online!

Outer (x) and inner (y) loop through the input list and keep the pair (x,y) only if x < y.

# Jelly, 2 bytes

Œc


Try it online!

• You ninja'd me - pretty print the output using something like ÇK€Y in the footer. Jun 19, 2017 at 20:10
• @JonathanAllan Oh, thanks! Jun 19, 2017 at 20:12

# 05AB1E, 3 bytes

### Code:

æ2ù


Uses the 05AB1E encoding. Try it online!

### Explanation:

æ      # Powerset of the input
2ù    # Keep the items of length two


## vim, 50 48

AX<esc>qqYplX@qq@qqrYpllDkxh@rq:g/./norm@r<cr>:g/X/d<cr>dG


Takes input in the form

abcd


and outputs as

ad
ac
ab
bd
bc
cd


### Explanation

First, AX<esc> appends an X to the input in order to handle 2-length input, which is necessary for reasons that will become clear shortly.

Then comes the first recursive macro, of the form qq...@qq@q. (Record macro q, run itself again at the end, end the recording, then run itself once.) In the body of the macro, Yp duplicates the current line, l breaks out of the macro if the line is now one character long, and X deletes the first character in the line. This has the end result of producing

abcdX
abcX
abX
aX
X
X


Ignoring the Xs for now, all we have to do is turn abcdX, for example, into ab / ac / ad / aX. This is achieved with the second recursive macro, qr...@rq.

In this macro, we first duplicate the line (Yp), then delete everything but the first two characters by moving right two (ll) and deleting to the end of the line (D). Since the cursor is now on the second charcater of the line, kx will delete the second character from the previous line, which happens to be the one that was just paired with the first character on the line. This process is then repeated starting again from the beginning of the line (h) as many times as necessary due to the recursive nature of the macro.

It's now just a matter of running the macro on every line, which can be achieved with :g/./norm@r (I'm not sure why this behaves differently than :%norm@r, but suffice to say, the latter does not work as intended.) Lines with X are deleted with :g/X/d, and the blank lines at the end left as a result of the construction of the r macro are cleaned up with dG.

• Great answer. Will take time for me to go through it. Jun 19, 2017 at 22:53

# Octave, 23 bytes

@(s)[nchoosek(+s,2) '']


Try it online!

# Python 3, 44 bytes

f=lambda k,*s:[*s]and[[k,x]for x in s]+f(*s)


Try it online!

Takes input as individual function parameters.

# Brachylog, 5 bytes

{⊇Ċ}ᶠ


Try it online!

## How it works

{⊇Ċ}ᶠ
ᶠ   find all the possible outputs of the following predicate
⊇          the output is an ordered subset of the input
Ċ         the output is a list with two elements


# R, 18 bytes

combn(scan(,''),2)


reads the list from stdin, returns a matrix where the columns are pairs.

Try it online!

# Python, 53 bytes

2 bytes saved thanks to @CalculatorFeline

lambda a:[(x,y)for i,x in enumerate(a)for y in a[:i]]


Try it online!

• a[i+1:] can be a[:i] Jun 19, 2017 at 20:21
• Having a long username makes short comments easy by simply mentioning the aforementioned user. Jun 19, 2017 at 20:59

# Octave, 49 48 bytes

@(x)[imag(y=(y=triu(x+j*x',1))(~~y)) real(y) '']


Anonymous function that avoids the built-in (nchoosek).

Try it online!

### Explanation

x+j*x' uses broadcasting to build a matrix of complex numbers where the real and imaginary parts are all pairs of code points from the input x.

y=triu(...,1) keeps the upper triangular part excluding the diagonal, making the rest of elements zero. The result is assigned to variable y.

y=(...)(~~y) retains the nonzero elements in the form of a column vector, which is assigned to variable y.

imag(...) and real(...) extract the real and imaginary parts.

[... ... ''] converts back to char to build the output.

• Nice! The whole challenge is really interesting. It took me about one hour and a half to come up with my es5 code (featured below). I am happy it generated so many interesting answers.. Jun 19, 2017 at 20:50

# Pari/GP, 34 bytes

a->concat([[[x,y]|y<-a,x<y]|x<-a])


Try it online!

# Python ≥ 2.7, 55 bytes

lambda l:list(combinations(l,2))
from itertools import*


repl.it!

# Perl 6, 17 bytes

*.combinations(2)


Whew, that's a long method name.

# Scala, 17 bytes

_.combinations(2)


# Pyth, 7 4 bytes

-3 bytes thanks to Leaky Nun!

.cQ2


Try it online!

• Jun 20, 2017 at 4:16
• @LeakyNun I could have sworn there was a function that did exactly what this challenge needed, but I only saw .C when looking through the list. Nice catch! Jun 20, 2017 at 15:35

# Ruby, 38 34 24 bytes

->x{[*x.combination(2)]}


Thanks Seims for the idea that saved 10 bytes.

Try it online!

• ->x{x.combination(2).to_a} saves some bytes :) Jun 22, 2017 at 12:19

# JavaScript ES6, 52 bytes

a=>a.map((x,i)=>a.slice(0,i).map(y=>[x,y])).slice(1)


If there was like a flatMap that would save a lot of bytes.

• Hey nice answer! check out my es5 answer while I study yours if u want. any feedback will be appreciated (positive/constructive haha) Jun 19, 2017 at 20:45
• Firefox 30's array comprehensions can simulate a flat map, e.g. a=>[for(x of[...a])for(y of(a.shift(),a))[x,y]].
– Neil
Jun 19, 2017 at 20:51
• @Neil, some really advanced syntax there... I d have to google at least three things to start understanding your expression. Namely the spread operator, what is array comprehensions and what is the [x,y] in the end (still havent found answer to that). Jun 19, 2017 at 21:17
• @alexandros84 The [x,y] at the end is the easy bit, it's just an array literal.
– Neil
Jun 19, 2017 at 21:19
• Also the spread operator is only there to copy the array, since I'm mutating it inside the loop.
– Neil
Jun 19, 2017 at 21:20

# Python, 55 bytes

f=lambda s:[(s,j)for j in s[1:]]+f(s[1:])if s else[]


Try it online!

Longer than other Python answers, but it uses a different technique so I think it's worth posting.

• Dont have time to check, I hope is really different technique cause I ve upvoted. Jun 20, 2017 at 2:54
• I think this is a very similar approach to @ovs's Python 3 answer.
– Neil
Jun 20, 2017 at 7:39

# Japt, 2 bytes

à2


Test it (-Q flag for visualisation purposes only)

# Python, 64 bytes

f=lambda a:sum((list(zip(a, a[i:]))for i in range(1,len(a))),[])


# Octave, 38 bytes

@(s)s([[x y]=find(s|s'),y](y<x,[2 1]))


Another answer to avoid nchoosek built-in.

Try it online!

## Clojure, 42 bytes

#(set(for[i % j(remove #{i}%)](set[i j])))


Returns a set of sets :)

# Python, 74 bytes

f=lambda a:[(c,d) for i,c in enumerate(a) for j,d in enumerate(a) if i<j]

• Welcome to PPCG! You can golf this: 1) replace 2-char variable names with 1-char 2) remove unnecessary whitespace 3) this is a snippet, you need to make it into a lambda, function or full program Jun 20, 2017 at 15:42
• Golfing off 10 bytes: 64 bytes Jun 22, 2017 at 11:48

# Javascript (ES 5), from 108 to 78 bytes

I post my answer today but I obviously promise to not accept my own answer:

x=input;
a=[];

for(n=0;n<(x.length-1);n++){for(i=n+1;i<(x.length);i++){a.push([x[n],x[i]]);}}

• Welcome to PPCG; we expect submissions to be golfed, including removing unnecessary whitespace Jun 20, 2017 at 3:04
• Ty. I was wondering also this: should I have included the x=input; a=[]; in my answer or not? I ll edit tomorrow. Jun 20, 2017 at 3:13
• You can either just submit a function or do a full program. Since you use a, you need to define it, but you can make a function of x. Jun 20, 2017 at 3:14
• much better now @HyperNeutrino. Jun 25, 2017 at 4:36
• I think you can exclude some semicolons and the empty line to save some space. I also think you can change for(i=n+1;i<(x.length);i++) to for(i=n;++i<x.length;). Likewise, you can change n<(x.length-1);n++ to n++<x.length-1 Jun 25, 2017 at 21:52

# J, 17 bytes

({~$#:I.@,)#\</#\  Try it online! ## Explanation ({~$#:I.@,)#\</#\  Input: string S
#\  Get the length of each prefix of S
#\      Get the length of each prefix of S again
</    Test using greater than (<) between each
,         Flatten
I.@          Find the indices where the value is 1
\$               Shape of that table
#:             Convert the indices to the base represented by the shape
{~                Index into S at those values