2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -1,20 +1,5 @@
|
|||
Given two [[set]]s ''A'' and ''B'', where ''A'' contains:
|
||||
|
||||
* John
|
||||
* Bob
|
||||
* Mary
|
||||
* Serena
|
||||
|
||||
and ''B'' contains:
|
||||
|
||||
* Jim
|
||||
* Mary
|
||||
* John
|
||||
* Bob
|
||||
|
||||
compute
|
||||
|
||||
:<math>(A \setminus B) \cup (B \setminus A).</math>
|
||||
;Task
|
||||
Given two [[set]]s ''A'' and ''B'', compute <math>(A \setminus B) \cup (B \setminus A).</math>
|
||||
|
||||
That is, enumerate the items that are in ''A'' or ''B'' but not both. This set is called the [[wp:Symmetric difference|symmetric difference]] of ''A'' and ''B''.
|
||||
|
||||
|
|
@ -22,6 +7,13 @@ In other words: <math>(A \cup B) \setminus (A \cap B)</math> (the set of items t
|
|||
|
||||
Optionally, give the individual differences (<math>A \setminus B</math> and <math>B \setminus A</math>) as well.
|
||||
|
||||
|
||||
;Test cases
|
||||
A = {John, Bob, Mary, Serena}
|
||||
B = {Jim, Mary, John, Bob}
|
||||
|
||||
|
||||
;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 <code>a = ["John", "Serena", "Bob", "Mary", "Serena"]</code> and <code>b = ["Jim", "Mary", "John", "Jim", "Bob"]</code> should produce the result of just two strings: <code>["Serena", "Jim"]</code>, in any order.
|
||||
# In the mathematical notation above <code>A \ B</code> gives the set of items in A that are not in B; <code>A ∪ B</code> gives the set of items in both A and B, (their ''union''); and <code>A ∩ B</code> gives the set of items that are in both A and B (their ''intersection'').
|
||||
<br><br>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,111 @@
|
|||
-- UNION AND DIFFERENCE
|
||||
|
||||
-- union :: [a] -> [a] -> [a]
|
||||
on union(xs, ys)
|
||||
nub(xs & ys)
|
||||
end union
|
||||
|
||||
-- difference :: [a] -> [a] -> [a]
|
||||
on difference(xs, ys)
|
||||
script except
|
||||
on lambda(a, y)
|
||||
if a contains y then
|
||||
|delete|(y, a)
|
||||
else
|
||||
a
|
||||
end if
|
||||
end lambda
|
||||
end script
|
||||
|
||||
foldl(except, xs, ys)
|
||||
end difference
|
||||
|
||||
|
||||
-- TEST
|
||||
|
||||
on run
|
||||
|
||||
set a to ["John", "Serena", "Bob", "Mary", "Serena"]
|
||||
set b to ["Jim", "Mary", "John", "Jim", "Bob"]
|
||||
|
||||
|
||||
-- 'Symmetric difference'
|
||||
|
||||
union(difference(a, b), difference(b, a))
|
||||
|
||||
--> {"Serena", "Jim"}
|
||||
|
||||
end run
|
||||
|
||||
|
||||
-- GENERIC LIBRARY FUNCTIONS
|
||||
|
||||
-- foldl :: (a -> b -> a) -> a -> [b] -> a
|
||||
on foldl(f, startValue, xs)
|
||||
tell mReturn(f)
|
||||
set v to startValue
|
||||
set lng to length of xs
|
||||
repeat with i from 1 to lng
|
||||
set v to lambda(v, item i of xs, i, xs)
|
||||
end repeat
|
||||
return v
|
||||
end tell
|
||||
end foldl
|
||||
|
||||
-- unique set of members of xs
|
||||
-- nub :: [a] -> [a]
|
||||
on nub(xs)
|
||||
if (length of xs) > 1 then
|
||||
set x to item 1 of xs
|
||||
[x] & nub(|delete|(x, items 2 thru -1 of xs))
|
||||
else
|
||||
xs
|
||||
end if
|
||||
end nub
|
||||
|
||||
-- uncons :: [a] -> Maybe (a, [a])
|
||||
on uncons(xs)
|
||||
if length of xs > 0 then
|
||||
{item 1 of xs, rest of xs}
|
||||
else
|
||||
missing value
|
||||
end if
|
||||
end uncons
|
||||
|
||||
-- deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a]
|
||||
on deleteBy(fnEq, x, xs)
|
||||
if length of xs > 0 then
|
||||
set {h, t} to uncons(xs)
|
||||
if lambda(x, h) of mReturn(fnEq) then
|
||||
t
|
||||
else
|
||||
{h} & deleteBy(fnEq, x, t)
|
||||
end if
|
||||
else
|
||||
{}
|
||||
end if
|
||||
end deleteBy
|
||||
|
||||
-- delete :: a -> [a] -> [a]
|
||||
on |delete|(x, xs)
|
||||
script Eq
|
||||
on lambda(a, b)
|
||||
a = b
|
||||
end lambda
|
||||
end script
|
||||
|
||||
deleteBy(Eq, x, xs)
|
||||
end |delete|
|
||||
|
||||
|
||||
-- Lift 2nd class handler function into 1st class script wrapper
|
||||
-- mReturn :: Handler -> Script
|
||||
on mReturn(f)
|
||||
if class of f is script then
|
||||
f
|
||||
else
|
||||
script
|
||||
property lambda : f
|
||||
end script
|
||||
end if
|
||||
end mReturn
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"Serena", "Jim"}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
iex(1)> a = Enum.into(~w(John Bob Mary Serena), HashSet.new)
|
||||
#HashSet<["Mary", "Serena", "John", "Bob"]>
|
||||
iex(2)> b = Enum.into(~w(Jim Mary John Bob), HashSet.new)
|
||||
#HashSet<["Mary", "Jim", "John", "Bob"]>
|
||||
iex(3)> sym_dif = fn(a,b) -> Set.difference(Set.union(a,b), Set.intersection(a,b)) end
|
||||
#Function<12.90072148/2 in :erl_eval.expr/5>
|
||||
iex(1)> a = ~w[John Bob Mary Serena] |> MapSet.new
|
||||
#MapSet<["Bob", "John", "Mary", "Serena"]>
|
||||
iex(2)> b = ~w[Jim Mary John Bob] |> MapSet.new
|
||||
#MapSet<["Bob", "Jim", "John", "Mary"]>
|
||||
iex(3)> sym_dif = fn(a,b) -> MapSet.difference(MapSet.union(a,b), MapSet.intersection(a,b)) end
|
||||
#Function<12.54118792/2 in :erl_eval.expr/5>
|
||||
iex(4)> sym_dif.(a,b)
|
||||
#HashSet<["Serena", "Jim"]>
|
||||
#MapSet<["Jim", "Serena"]>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
((a, b) => {
|
||||
'use strict';
|
||||
|
||||
|
||||
let // UNION AND DIFFERENCE
|
||||
|
||||
// union :: [a] -> [a] -> [a]
|
||||
union = (xs, ys) => unionBy((a, b) => a === b, xs, ys),
|
||||
|
||||
// difference :: [a] -> [a] -> [a]
|
||||
difference = (xs, ys) =>
|
||||
ys.reduce((a, y) =>
|
||||
a.indexOf(y) !== -1 ? (
|
||||
delete_(y, a)
|
||||
) : a.concat(y), xs),
|
||||
|
||||
|
||||
|
||||
// GENERAL PRIMITIVES
|
||||
|
||||
// unionBy :: (a -> a -> Bool) -> [a] -> [a] -> [a]
|
||||
unionBy = (f, xs, ys) => {
|
||||
let sx = nubBy(f, xs),
|
||||
sy = nubBy(f, ys);
|
||||
|
||||
return sx.concat(
|
||||
sx
|
||||
.reduce(
|
||||
(a, x) => deleteBy(f, x, a),
|
||||
sy
|
||||
)
|
||||
)
|
||||
},
|
||||
|
||||
// deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a]
|
||||
deleteBy = (f, x, xs) =>
|
||||
xs.reduce((a, y) => f(x, y) ? a : a.concat(y), []),
|
||||
|
||||
// delete_ :: a -> [a] -> [a]
|
||||
delete_ = (x, xs) =>
|
||||
deleteBy((a, b) => a === b, x, xs),
|
||||
|
||||
// nubBy :: (a -> a -> Bool) -> [a] -> [a]
|
||||
nubBy = (f, xs) => {
|
||||
let x = (xs.length ? xs[0] : undefined);
|
||||
|
||||
return x !== undefined ? [x].concat(
|
||||
nubBy(f, xs.slice(1)
|
||||
.filter(y => !f(x, y))
|
||||
)
|
||||
) : [];
|
||||
};
|
||||
|
||||
|
||||
|
||||
// 'SYMMETRIC DIFFERENCE'
|
||||
|
||||
return union(
|
||||
difference(a, b),
|
||||
difference(b, a)
|
||||
);
|
||||
|
||||
})(
|
||||
["John", "Serena", "Bob", "Mary", "Serena"],
|
||||
["Jim", "Mary", "John", "Jim", "Bob"]
|
||||
);
|
||||
|
|
@ -0,0 +1 @@
|
|||
["Serena", "Jim"]
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
my $A = set <John Serena Bob Mary Serena>;
|
||||
my $B = set <Jim Mary John Jim Bob>;
|
||||
my \A = set <John Serena Bob Mary Serena>;
|
||||
my \B = set <Jim Mary John Jim Bob>;
|
||||
|
||||
say $A (^) $B;
|
||||
say A ∖ B; # Set subtraction
|
||||
say B ∖ A; # Set subtraction
|
||||
say A ⊖ B; # Symmetric difference
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
$A = @( "John"
|
||||
"Bob"
|
||||
"Mary"
|
||||
"Serena" )
|
||||
|
||||
$B = @( "Jim"
|
||||
"Mary"
|
||||
"John"
|
||||
"Bob" )
|
||||
|
||||
# Full commandlet name and full parameter names
|
||||
Compare-Object -ReferenceObject $A -DifferenceObject $B
|
||||
|
||||
# Same commandlet using an alias and positional parameters
|
||||
Compare $A $B
|
||||
|
||||
# A - B
|
||||
Compare $A $B | Where SideIndicator -eq "<=" | Select -ExpandProperty InputObject
|
||||
|
||||
# B - A
|
||||
Compare $A $B | Where SideIndicator -eq "=>" | Select -ExpandProperty InputObject
|
||||
Loading…
Add table
Add a link
Reference in a new issue