Hey, Buddy!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import Data.Set (Set)
import qualified Data.Set as Set

{--

Okay, I shot myself in the foot yesterday in that my brute-force lotto
definition included the complete implementation for choose. So, today,
I cannot say 'P26: generate the combinations of K distinct objects chosen
from N elements of a list, blah-blah-blah, ...' because you'll just copy-n-
paste my code from yesterday and crow, triumphantly: 'HA! FRIST! geophf!'

And I'll be innundated with 'FRIST!' tweets, left, right, and centre.

('FRIST' is from the gaming community: responders are so eager to be the
first-response post they accidentally misspell (originally, and now: 
intentionally) the first and only word in their first-response post.)

So I can't copy-n-paste P26, because you'll just copy-n-paste the solution,
and what's the fun of that?

So, onto the next problem, P27, of the P-99 problem set: Set-to-sets-of-sets.

Say you have the data type: --}

data Buddy = Alexandra | Beth | Carla | Da5id | Elie
           | Franny | Graeme | Henry | Isaac
   deriving (Eq, Ord, Enum, Show, Read)

{--

a. The P-27 problem statement begins: "In how many ways, ..." 
blah-di-blah-di-blah.

That is: enumerate the combinations of the sets of 2, 3, 4 buddies from the
set of all the buddies declared above. How many "unique" 2-3-4-combinations
are there? Question (or, more properly, 'pensée'): why do I put 'unique' in 
quotes for Haskell, whereas in Prolog I would have to ... *ahem* 'assert' 
that uniqueness?

If you don't get the humour, please forgive my perchant to parlay in `pataphor.

b. Define a function --}

bunch :: (Eq a, Ord a) => Set a -> [Int] -> Set (Set (Set a))
bunch buddies cliques = undefined

{-- such that a set of elements are subdivided into sets of cliques, so,
for example:

let buddies = Set.fromList [Alexandra .. Isaac]
in  bunch buddies [2,2,5] ~>
    fromList [fromList [fromList [Alexandra, Beth], fromList [Carla, Da5id],
                        fromList [Elie, Franny, Graeme, Henry, Isaac]], ...]

... and, yes, I 'went there' with a setof-setof-sets. Suggestions for
a better return-type of this function called 'not-group-but-bunch-just-because'?

Note at the bottom of P27:

'You may find more about this combinatorial problem in a good book on 
discrete mathematics under the term "multinomial coefficients".'

Yeah. That.

A(n inefficient) solution to this problem is at http://lpaste.net/107273

Update: the solution now properly guards uniqueness inline, so it has been
'efficientized' for your reviewing pleasure.

 --}