/*
Symmetric difference (Rosetta code) in Picat.
http://rosettacode.org/wiki/Symmetric_difference
"""
Given two sets A and B, where A contains:
John
Bob
Mary
Serena
and B contains:
Jim
Mary
John
Bob
compute
(A \setminus B) \cup (B \setminus A).
That is, enumerate the items that are in A or B but not both. This set is called the symmetric
difference of A and B.
In other words: (A \cup B) \setminus (A \cap B) (the set of items that are in at least
one of A or B minus the set of items that are in both A and B).
Optionally, give the individual differences (A \setminus B and B \setminus A) as well.
Notes
- If your code uses lists of items to represent sets then ensure duplicate items in
lists are correctly handled. For example two lists representing sets of
a = ["John", "Serena", "Bob", "Mary", "Serena"] and
b = ["Jim", "Mary", "John", "Jim", "Bob"]
should produce the result of just two strings:
["Serena", "Jim"],
in any order.
- In the mathematical notation above A \ B gives the set of items in A that are
not in B; A ∪ B gives the set of items in both A and B, (their union); and A ∩ B
gives the set of items that are in both A and B (their intersection).
"""
This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com
See also my Picat page: http://www.hakank.org/picat/
*/
import ordset.
main => go.
go =>
A = ["John", "Serena", "Bob", "Mary", "Serena"].new_ordset(),
B = ["Jim", "Mary", "John", "Jim", "Bob"].new_ordset(),
println(symmetric_difference=symmetric_difference(A,B)),
println(symmetric_difference2=symmetric_difference2(A,B)),
println(subtractAB=subtract(A,B)),
println(subtractBA=subtract(B,A)),
println(union=union(A,B)),
println(intersection=intersection(A,B)),
nl.
symmetric_difference(A,B) = union(subtract(A,B), subtract(B,A)).
% variant
symmetric_difference2(A,B) = subtract(union(A,B), intersection(B,A)).