# Symmetric difference

Surprised that we don't have a symmetric difference challenge yet.

Given two lists only containing positive integers, return all items among these two lists that aren't contained in both of the lists.

## Rules

From the set definition:

A set is a collection of definite distinct items.

• So you can assume the items in the input lists are always unique.
• You can also take input as a set if your language supports it.

## Test cases

Here is a sample program that generates the test cases.

[1,2,3],[2,3,4] -> [1,4]

• C++ has a builtin but it doesn't work. I'm going to go ask on Stack Overflow. Apr 14, 2020 at 16:25

# APL (Dyalog Unicode), 3 bytes

∪~∩


Try it online!

### How it works

∪~∩  ⍝ Input: two sets as vectors
∪    ⍝ Set union
~   ⍝ Set minus
∩  ⍝ Set intersection


The rest is just for fun.

# APL (Dyalog Unicode), 4 bytes

~∪~⍨


Try it online!

~∪~⍨
~     ⍝ Set difference (a~b)
∪    ⍝ Set union
~⍨  ⍝ Set difference reversed (b~a)


# APL (Dyalog Unicode), 5 bytes

~⍨∪⍨~


Try it online!

This one is palindromic!

### How it works

~⍨∪⍨~
~⍨     ⍝ Set difference reversed (b~a)
∪⍨   ⍝ Set union reversed
~  ⍝ Set difference (a~b)

• The only symmetric answer so far.
Apr 12, 2020 at 12:58

# Python 3, 11 bytes

set.__xor__


Try it online!

For built-in set objects, a^b computes symmetrical set difference. __xor__ is the magic name for that operator, and it is shorter than lambda a,b:a^b.

Also works in Python 2.

# J, 8 6 bytes

-2 bytes thanks to Bubbler!

-.,-.~


Try it online!

# K (oK), 11 bytes

{(x^y),y^x}


Try it online!

• Shouldn't -.,-.~ work in J? Apr 12, 2020 at 11:24
• @Bubbler Yes, thanks! Apr 12, 2020 at 11:52

# Bash, 22 19 bytes

-3 bytes thanks to @user41805

rs 0 1|sort|uniq -u


Try it online!

• rs 0 1 is shorter than tr Apr 13, 2020 at 7:53

# Wolfram Language (Mathematica), 35 bytes

Join@##~Complement~Intersection@##&


Try it online!

# 05AB1E, 5 bytes

«¹²ÃK


Try it online!

### How?

«     - merge the two input lists   -> a+b
¹    - push 1st input list            a,a+b
²   - push 2nd input list            b,a,a+b
Ã  - intersection                   b&a,a+b


# C (gcc), 98 96 bytes

*d;f(a,b,c)int*a,*b,*c;{for(;*c=*a++;c+=!(*d=-*d))for(d=b;*d&&*d-*c;d++);for(;*c=*b++;c+=*c>0);}


Try it online!

-2 bytes thanks to @ceilingcat

Input is in two 0-terminated arrays a and b, output as a 0-terminated array into preallocated buffer c.

• Looks like it would be break-even to use a standard f(int*a,int*b,int*c){ instead of K&R. The repeated a,*b,*c; part is 8 bytes, same as 2x int*. No saving but nicer to read :/ Apr 14, 2020 at 2:19

# R, 45 39 bytes

function(x,y,-=setdiff)union(x-y,y-x)


Try it online!

Thanks to user Kirill L.'s comment.

The original was the following.

function(x,y){s=setdiff;union(s(x,y),s(y,x))}


Try it online!

Straightforward, definition coded in R.

Note: the following function is also 45 bytes. I thought that to define s=setdiff first would save a few bytes but as it turns out the function will need a semi-colon instruction separator and to be between braces. For the same byte count a no-tricks function is more natural.

function(x,y)union(setdiff(x,y),setdiff(y,x))

• You can still avoid those braces by aliasing setdiff inside function definition. And in this particular case you can save even more bytes, by aliasing it not as a variable, but as an operator! Try it online! Apr 26, 2020 at 17:47

# Red, 25 bytes

func[a b][difference a b]


Try it online!

• Sounds like difference (10 bytes) should be a valid solution...? Apr 12, 2020 at 11:29
• @Bubbler I don't know - it would be just a word - neither a program nor a function. Apr 12, 2020 at 11:54
• @Bubbler Something like this? Apr 12, 2020 at 11:57
• Yeah. I think it is valid under CGCC rule because the word itself is reusable (even if you can't easily assign it to a different name). Apr 12, 2020 at 12:30

# 05AB1E, 6 bytes

«©ʒ®s¢


How does it work?

« merge lists
© store in the global register
ʒ keep only items which
®s¢ the number of times which they appear in the merged list is truthy, which is only 1 in 05AB1E


Try it online!

# Charcoal, 8 bytes

Ｉ⁺⁻θη⁻ηθ


Try it online! Link is to verbose version of code. Explanation:

   θ        First input
η       Second input
⁻         Remove matching elements
η     Second input
θ    First input
⁻      Remove matching elements
⁺          Concatenate
Ｉ           Cast to string
Implicitly print


# JavaScript (ES6), 46 bytes

Takes input as (a)(b), where $$\a\$$ and $$\b\$$ are Sets. Returns a list.

JS has very few set built-ins, so this a bit verbose.

a=>b=>[...a,...b].filter(x=>a.has(x)^b.has(x))


Try it online!

# MATL, 2 bytes

X~


Try it online!

### Explanation

Built-in. Implicit inputs, implicit output.

# Ruby, 16 14 bytes

->a,b{a-b|b-a}


Try it online!

# Julia, 7 bytes

symdiff


Try it online!

# 05AB1E, 4 bytes

«Ð¢Ï


Try it online.

Explanation:

      #  i.e. inputs: [1,2,3] and [2,3,4]
«     # Merge the two (implicit) input-lists together
#  STACK: [[2,3,4,1,2,3]]
Ð    # Triplicate this merged list
#  STACK: [[2,3,4,1,2,3],[2,3,4,1,2,3],[2,3,4,1,2,3]]
¢   # Count all occurrences of the values in the list
#  STACK: [[2,3,4,1,2,3],[2,2,1,1,2,2]]
Ï  # Only leave the values at the truthy (count = 1) indices
#  STACK: [[4,1]]
# (after which the result is output implicitly)


x%y=filter(notElemy)x
x#y=x%y++y%x


Try it online!

# Jelly, 2 bytes

œ^


It's a two-byte dyadic atom (i.e. a built-in).

Try it online!

# Icon, 38 bytes

procedure f(a,b)
return a++b--a**b
end


Try it online!

# Groovy, 18 bytes

f={a,b->a-b+(b-a)}


Try it online!

# PowerShell, 39 bytes

param($a,$b)$a+$b|group|? c* -eq 1|% n*


Try it online!

unrolled:

param($a,$b)
$a+$b|group|where count -eq 1|% name


# Pyth, 5 bytes

-sQ@F


Try it online!

 sQ   sum inputs (union since inputs are sets)
-     minus
@F intersection of inputs


# Perl 5, 42 bytes

sub u{map$k{$_}++,@_;grep$k{$_}==1,keys%k}


Try it online!

## Pascal, ≥ 4 B

The symmetric difference operator denoted >< is defined by ISO standard 10206 “Extended Pascal” as part of the programming language.

A><B        { where A and B are assignment-compatible set expressions }


In “Standard Pascal”, defined by ISO standard 7185, you will need to resort to basic operators:

(A−B)+(B−A)


# Python, 49 bytes (no built-in set operations)

lambda s,t:[a for a in s+t if(a in s)*(a in t)<1]


Attempt This Online!

takes two lists as input, returns symmetric difference of those lists (concatenation without elements that appear in both lists)

## Python, 22 bytes

lambda s,t:(s-t)|(t-s)

lambda s,t:(s|t)-(t&s)


build symmetric difference as union of differences / union without intersection

# Factor + sets.extras, 14 bytes

symmetric-diff


Try it online!

No builtin:

# Factor + math.unicode, 25 bytes

[ 2dup ∪ -rot ∩ ∖ ]


Try it online!