summaryrefslogtreecommitdiff
path: root/week3/camil/StdSortList.icl
blob: 21778bddcc0a130705c579fff1519c2d4cadddc2 (plain) (blame)
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
// Ik kreeg het alleen werkend door de .dcl ook aan te passen. 
// Met een record dat het maximum bijhoudt moet je er namelijk vanuit kunnen gaan dat zero gedefinieerd is voor type a.

implementation module StdSortList

import StdEnv

::  SortList a = {list :: [a], max :: a}

newSortList   :: (SortList a) | zero a
newSortList = {list=[], max=zero}

memberSort    :: a (SortList a) -> Bool       | Eq, Ord a      // is element van
memberSort _ {list=[],max=_} = False
memberSort m l
    | minimum l == m = True
    | minimum l > m = False
    | otherwise = memberSort m {list=(tl l.list),max=l.max}

insertSort    :: a (SortList a) -> SortList a | Ord a          // voeg element toe
insertSort m l = insertSort` {list=[],max=l.max} m l 
where 
    insertSort` :: (SortList a) a (SortList a) -> (SortList a) | Ord a
    insertSort` l1 m l2
        | count l2 == 0 = {list=l1.list ++ [m], max=m}
        | minimum l2 >= m = {list=l1.list ++ [m] ++ l2.list, max=l2.max}
        | otherwise = insertSort` {list=l1.list ++ [hd l2.list], max=hd l2.list} m {list=(tl l2.list), max=l2.max}

removeFirst   :: a (SortList a) -> SortList a | Eq, Ord, zero a      // verwijder eerste voorkomen
removeFirst m l = removeFirst` newSortList m l
where
    removeFirst` :: (SortList a) a (SortList a) -> (SortList a) | Eq, Ord a
    removeFirst` l1 m l2
        | count l2 == 0 = l1
        | minimum l2 > m = {list=l1.list ++ l2.list, max=l2.max}
        | minimum l2 == m && count l2 == 1 = {list=l1.list ++ tl l2.list, max=l1.max}
        | minimum l2 == m = {list=l1.list ++ tl l2.list, max=l2.max}
        | otherwise = removeFirst` {list=(l1.list ++ [hd l2.list]),max=hd l2.list} m {list=(tl l2.list), max=l2.max}

removeAll     :: a (SortList a) -> SortList a | Eq, Ord, zero a      // verwijder alle voorkomens
removeAll m l = removeAll` newSortList m l
where
    removeAll` :: (SortList a) a (SortList a) -> (SortList a) | Eq, Ord a
    removeAll` l1 m l2
        | count l2 == 0 = l1
        | minimum l2 > m = {list=l1.list ++ l2.list, max=l2.max}
        | minimum l2 == m = removeAll` l1 m {list=tl l2.list, max=l2.max}
        | otherwise = removeAll` {list=l1.list ++ [hd l2.list], max=hd l2.list} m {list=tl l2.list,max=l2.max}

elements      ::   (SortList a) -> [a]                         // geef alle elementen
elements l = l.list

count         ::   (SortList a) -> Int                         // aantal elementen
count l = length l.list

minimum       ::   (SortList a) -> a                           // huidige minimum waarde
minimum l = hd l.list

maximum       ::   (SortList a) -> a                           // huidige maximum waarde
maximum l = l.max

mergeSortList :: (SortList a) (SortList a) -> SortList a | Eq, Ord, zero a // meng gesorteerde lijsten
mergeSortList l1 {list=[],max=_} = l1
mergeSortList l1 l2 = mergeSortList (insertSort (hd l2.list) l1) {list=tl l2.list,max=l2.max}