sourcelibs/Sets/src/Sets.xtl
1⍝# Sets: vectors as sets -- union, intersection, difference, subset,
2⍝# and how often each item occurs.
3⍝# Import it with an alias of your choice: "se:" u_se< "Sets".
4⍝# Put libs/Sets/src on XETAL_PATH ("just path"); the reference is libs/Sets/docs.
5⍝# Names with l: are exported; those under h: are private to this file.
6⍝#
7⍝# A set is a vector of any type with equality (numbers, characters,
8⍝# boxes); results have no repeats and keep the order in which items
9⍝# are first seen, left argument first.
10
11⍝## Combining
12
13⍝# a u_nion b: the items of either.
14ˡu̲nion ← { a b → u̲nique a c̲at b }
15
16⍝# a i_ntersect b: the items of a that are also in b.
17ˡi̲ntersect ← { a b → u ← u̲nique a◆ (u m̲ember? b) r̲eplicate u }
18
19⍝# a d_ifference b: the items of a that are not in b.
20ˡd̲ifference ← { a b → u ← u̲nique a◆ (n̲ot u m̲ember? b) r̲eplicate u }
21
22⍝# a s_ymmetric b: the items in one but not both.
23ˡs̲ymmetric ← { a b → (a ˡd̲ifference b) c̲at b ˡd̲ifference a }
24
25⍝## Comparing
26
27⍝# a s_ubset? b: whether every item of a is in b.
28ˡs̲ubset? ← { a b → '∧ r̲/ a m̲ember? b }
29
30⍝# a s_ame? b: whether a and b hold the same items, ignoring order and
31⍝# repeats.
32ˡs̲ame? ← { a b → (a ˡs̲ubset? b) ∧ b ˡs̲ubset? a }
33
34⍝# a d_isjoint? b: whether no item is in both.
35ˡd̲isjoint? ← { a b → n̲ot '∨ r̲/ a m̲ember? b }
36
37⍝## Counting
38
39⍝# c_ounts v: how often each item of u_nique v occurs in v, in that order.
40ˡc̲ounts ← { v → '{ t̲ally w̲here v = ⍵ } e̲ach u̲nique v }
41
42⍝# m_ode v: the items that occur most often, first seen first.
43ˡm̲ode ← { v →
44 c ← ˡc̲ounts v
45 (c = 'm̲ax r̲/ c) r̲eplicate u̲nique v
46}