# 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. – S.S. Anne Apr 14 '20 at 16:25

# Jelly, 2 bytes

œ^


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

Try it online!

# 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. – Adám Apr 12 '20 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? – Bubbler Apr 12 '20 at 11:24
• @Bubbler Yes, thanks! – Galen Ivanov Apr 12 '20 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 – user41805 Apr 13 '20 at 7:53

# 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 :/ – Peter Cordes Apr 14 '20 at 2:19

# Wolfram Language (Mathematica), 35 bytes

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


Try it online!

# Red, 25 bytes

func[a b][difference a b]


Try it online!

• Sounds like difference (10 bytes) should be a valid solution...? – Bubbler Apr 12 '20 at 11:29
• @Bubbler I don't know - it would be just a word - neither a program nor a function. – Galen Ivanov Apr 12 '20 at 11:54
• @Bubbler Something like this? – Galen Ivanov Apr 12 '20 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). – Bubbler Apr 12 '20 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)


# 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! – Kirill L. Apr 26 '20 at 17:47

# 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!