Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Your goal is to compute the set intersection of two lists of integers. The intersection is defined as the unique un-ordered group of integers found at least once in both input list.


The input may be in any format desired (function parameter, stdio, etc.), and consists of two lists of integers. You many not assume anything about each list other than they may contain any non-negative number of integers (i.e. they are unsorted, possibly may contain duplicates, may have different lengths, and may even be empty). It is assumed that each integer will fit in your language's native signed integer type, may be more than 1 decimal digit long, and are signed.

Example input:

1 4 3 9 8 8 3 7 0
10 1 4 4 8 -1


The output is any list-like of integers representing the set intersection of the two lists to any format desired (return value, stdio, etc.). There is no requirement that the output be sorted, though you are welcome to provide an implementation that happens to always be sorted. The output must form a valid un-ordered set (e.g. it must not contain any duplicate values).

Example test cases (note that the order of the output is not important):

First two lines are the input lists, third line is the output. (empty) denotes the empty list.



3 1 2 4 3 1 1 1 1 3
3 1 -1 0 8 3 3 1
1 3

1 2 1
3 3 4


This is code golf; shortest answer in bytes wins.

Standard loop-holes are prohibited. You may use any built-in features not designed for set-like operations.

Prohibited built-in features:

  • set creation/removing duplicates
  • set difference/intersection/union
  • Generalized membership testing (e.g. anything similar to the in keyword in Python, indexOf-like functions, etc). Note that the use of "foreach item in list" constructs are allowed (assuming they don't violate any of the other restrictions), despite the fact that Python re-uses the in keyword to create this construct.
  • These prohibited built-ins are "viral", i.e. if there's a larger built-in containing any of these sub-features, it is similarly prohibited (e.g. filtering by membership in a list).

Any built-ins not on the above list are allowed (ex. sorting, integer equality testing, list append/remove by index, filtering, etc.).

For example, take the following two example snippets (Python-like code):

# prohibited: filters by testing if each value in tmpList is a member of listA
result = tmpList.filter(listA)

# ok: filtering by a lambda which manually iterates over listA and checks for equality
def my_in_func(val, slist):
    for a in slist:
        if(val == a):
            return True
    return False
result = filter(lambda v: my_in_func(val, listA), tmpList)

You are welcome to implement any of these set-like features yourself and they will count towards your score.

Your solution should complete in a reasonable amount of time (say, less than a minutes on whatever hardware you have for two lists ~length 1000 each).

share|improve this question
By the way, confusion and miscommunication are common in do X without Y, which is why they are officially one of the thing to avoid when writing challenges. – Dennis Mar 6 at 0:06
@Dennis Yeah, I guess this problem really has become one of those :( When I first wrote it, I was hoping it might be an interesting problem, but as soon as I started working out a ruleset I should have just killed the challenge. – helloworld922 Mar 6 at 0:18
Is a builtin which performs run length encoding allowed? – isaacg Mar 6 at 19:46
That should be fine. – helloworld922 Mar 6 at 20:08
May there be duplicates in the output? – Adám Mar 8 at 21:16

Jelly, 13 bytes


Try it online!

How it works

ṂrṀ{ç³ç  Main link. Arguments: A (list 1), B (list 2)

Ṃ        Yield m, the minimum of A.
  Ṁ{     Yield M, the maxmimum of A.
 r       Create an inclusive range from m to M.
    f³   Apply the helper link with right argument A.
      f  Apply the helper link with right argument B.

=S¥Ðf    Helper link. Arguments: n (integer in range), L (list, A or B)

=        Test all elements of L for equality with n.
 S       Add the results.
  ¥      Combine the two previous links into a dyadic chain.
   Ðf    Filter by the result of the sums.
share|improve this answer
@isaacg Fixed now. – Dennis Mar 6 at 0:02

MATL, 18 bytes


Try it online!

This works in two steps. First the intersection is computed, possibly with duplicates. This is based on comparing all elements of one array with all elements of the other, and keeping elements of the first that are present in the second.

Then duplicates are removed. For this, the array from the previous step is sorted, and entries are kept if different from the preceding. A -inf value is prepended so that the first (i.e. lowest) value is not lost.

YY_                 % push -infinity
   it               % take first input. Duplicate
     i!             % take second input. Transpose
        =           % test all combinations of elements of the two inputs for equality
        Xa          % row vector that contains true for elements of first array that 
                    % are present in the second, possibly duplicated
          )         % index into first array to keep only those elements. Now we need
                    % to remove duplicates
           h        % append -infinity
            S       % sort
             tdf    % duplicate. Find entries that differ from the preceding
                Q)  % add 1 and index into array to keep only non-duplicates
share|improve this answer

golflua, 68 chars

\f(a,b)k={}~@_,v p(a)~@_,w p(b)?w==v k[w]=w$$$~@_,v p(k)I.w(v," ")$$

which is called as

> f({1,2,3,4},{3,4,5})
3 4
> f({3,1,2,4,3,1,1,1,1,3},{3,1,-1,0,8,3,3,1})
3 1

In regular Lua, this would be

function foo(a,b)
   local k={}
   for i,v in pairs(a)
      for j,w in pairs(b)
         if v==w then
            k[v] = v
   for i,v in pairs(k)
      print(v," ")

So basically I'm iterating over the each element of the two tables and only storing the equivalent values. By using the value as the key (k[w]=w), I'm eliminating all duplicates. We then output the new table by iterating over the index & value of pairs

share|improve this answer

Haskell, 45 bytes

f y=foldl(\s e->s++[e|any(==e)y,all(/=e)s])[]

Example usage: f [3,1,2,4,3,1,1,1,1,3] [3,1,-1,0,8,3,3,1] -> [3,1].

Starting with the empty list as an accumulator go through one of the input lists and add it's elements to the accumulator if it's in the other list but not in the accumulator so far. Membership of e in y is tested with any(==e)y. Not-membership with all(/=e)y.

share|improve this answer

JavaScript (ES6), 66 bytes


Without using indexOf, as I'm not convinced that it's permitted.

share|improve this answer

Pyth, 12 11 bytes




               Implicit: Q is one of the lists.
     q#RQE     For every element in the first list, filter the second list on
               equality with that element.
    s          Concatenate. We now have the intersection, with duplicates.
  rS      8    Sort and run length encode, giving counts and elements.
eM             Take just the elements.
share|improve this answer
Sorting and rle saves one byte. – Jakube Mar 6 at 18:54
@Jakube I would say rle is a builtin which removes duplicates. – isaacg Mar 6 at 19:38
It only removes duplicates if you sort it before and remove the counts of the rle afterwards. It's a little bit in a grey area, but I think so is using a dictionary. It's basically a set that stores additional data for each element. – Jakube Mar 6 at 19:42
@Jakube OP says it's fine. Thanks! – isaacg Mar 8 at 20:52

bash + GNU coreutils, 184 Bytes

[ -z "$1" ] && exit
p='{if(a[$0]++==0)print $0}'
while read A; do
while read B; do
[ $A = $B ] && echo $A
done < <(grep -oP '\d*'<<<$1|awk "$p")
done < <(grep -oP '\d*'<<<$2|awk "$p")


./ '12 4 654 12 3 56' '4 4 56 33 3 3 3'



No output if intersection is empty. This script does not sort and makes sanity check if first set is empty. Explanation:

[ -z "$1" ] && exit  # Exit if first set is empty
p='{if(a[$0]++==0)print $0}' # The AWK program we will use
while read A; do   # read the list with two
while read B; do   # encapsulated loops
[ $A = $B ] && echo $A   # if they match, then print
done < <(grep -oP '\d*'<<<$1|awk "$p")
done < <(grep -oP '\d*'<<<$2|awk "$p")
# the process substitution greps the numbers and pipes them to awk. Our awk program makes them unique without sorting; it uses associative arrays with index names same as lines (our numbers here).

Bonus to know: You could change to grep -o . to do this with random strings instead of numbers.

share|improve this answer

Perl 6, 26 37 bytes



> my &f = {%(@^a.grep(any(@^b)):p.invert).keys}
-> @a, @b { #`(Block|559823336) ... }
> f([3,1,2,4,3,1,1,1,1,3], [3,1,-1,0,8,3,3,1])
(1 3)

Cheeky non-competing answer

> [3,1,2,4,3,1,1,1,1,3] ∩ [3,1,-1,0,8,3,3,1]
set(3, 1)

or if you like it in a boring ol' f function

> my &f = &infix:<∩>
sub infix:<∩> (|p is raw) { #`(Sub+{<anon|130874592>}+{Precedence}|102325600) ... }
> f([3,1,2,4,3,1,1,1,1,3], [3,1,-1,0,8,3,3,1])
set(3, 1)
share|improve this answer
I've updated my answer to not use .unique – LockOpeners Mar 6 at 1:07

Retina, 63 bytes

The last two lines remove duplicates. The input is two space-delimited lists separated by a comma. The output is whitespace-delimited.

+`( -?\d+)\b(.*,.*)\1\b


Try it online

If duplicates in the output are allowed, my program would be 42 bytes.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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