ARCHIVE

O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|

View on GitHub

OPERATIONS ON SETS

All of this assumes your set has no repeated elements. If you aren’t sure, you can use this.

> removeRepeats :: [Integer] -> [Integer]
> removeRepeats [] = []
> removeRepeats (a:as) = if a `elem` as then removeRepeats as else a : removeRepeats as

ghci> removeRepeats [1,1,1,2,2,3,4,5,3,5]
[1,2,4,3,5]

To find the intersection of two sets we extract all those elements from as that are also in bs.

> intersection :: [Integer] -> [Integer] -> [Integer]
> intersection []     bs = []
> intersection (a:as) bs = if a `elem` bs then a:(intersection as bs) else intersection as bs

ghci> intersection [1,2,3] [2,3,4]
[2,3]

To find the union, we concatenate our lists, then remove repeats, then sort.

> union        :: [Integer] -> [Integer] -> [Integer]
> union as bs = sort (removeRepeats (as ++ bs))
 
ghci> union [1,2,3] [2,3,4]
[1,2,3,4]

To find the difference, we find the intersection of as and bs, then only return the elements of as that aren’t in the intersection.

> difference :: [Integer] -> [Integer] -> [Integer]
> difference as bs = sort (difference2 as (intersection as bs))

> difference2 :: [Integer] -> [Integer] -> [Integer]
> difference2 []     bs = []
> difference2 (a:as) bs = if a `elem` bs then difference2 as bs else a:(difference2 as bs)

ghci> difference [1,2,3] [2,3,4]
[1]

The disjunction is the difference of the union and intersection.

> disjunction :: [Integer] -> [Integer] -> [Integer]
> disjunction as bs = difference (union as bs) (intersection as bs)

ghci> disjunction [1,2,3] [2,3,4]
[1,4]

These functions will also be useful later.

> len :: [Integer] -> Integer
> len []     = 0
> len (a:as) = 1+len as

ghci> len [1,2,3,4,5]
5

> list1ton :: Integer -> [Integer]
> list1ton n | n<1 = []
> list1ton n = n:(list1ton (n-1))

ghci> list1ton 10
[10,9,8,7,6,5,4,3,2,1]

> lcg :: Integer -> Integer -> [Integer]
> lcg _ 1    = [1]
> lcg seed i = do 
>   let n = inst seed 
>   (((n `mod` i)+1) : (lcg n (i-1)))

ghci> lcg 5641421 9
[3,4,6,4,3,4,1,2,1]
ghci> lcg 235234 9 
[5,1,1,1,3,1,2,1,1]
ghci> lcg 234 9   
[2,1,1,5,5,1,3,1,1]
ghci> lcg 2331414 9
[5,5,7,5,5,1,3,1,1]

> inst :: Integer -> Integer
> inst r = ((5397*r+7901) `mod` 65536) 

It is now time for the unary operation, permutation of a set. The seed lets us get our array of random numbers from the linear congruential generator.

> permute :: Integer -> Integer -> [Integer]
> permute seed n = do 
>   let as = list1ton n
>   let bs = lcg2 seed n
>   permute2 as bs []

> permute2 :: [Integer] -> [Integer] -> [Integer] -> [Integer]
> permute2 as [] cs = cs 
> permute2 as (b:bs) cs = do
>   let n          = len as
>   let (ds, e:es) = splitAt (fromIntegral (b-1)) as
>   permute2 (ds++es) bs (e:cs) 

ghci> permute 65273853 9
[9,2,8,1,5,4,7,6,3]
ghci> permute 325321 4
[1,4,3,2]
ghci> permute 653 9  
[6,4,8,2,3,7,1,5,9]
ghci> permute 23198953 50 
[1,5,37,42,46,39,10,48,40,33,29,15,2,16,38,32,
 8,21,34,7,6,18,23,12,31,24,47,30,3,26,45,9,14,
 22,28,44,27,17,36,20,11,49,19,13,25,4,43,41,35,50]
ghci> len (permute 3248392 100)
100