summaryrefslogtreecommitdiffstats
path: root/AufgabeFFP8.hs
blob: 27475972d405e866b1ebbaebd74fbcfd724e22fd (plain)
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
module AufgabeFFP8
where

import Data.Array
import Data.List hiding ((\\))
import Test.QuickCheck

type Nat = Int

-- Minfree basic version

minfree_bv :: [Int] -> Int
minfree_bv xs = head ([0..] \\ xs)

(\\) :: Eq a => [a] -> [a] -> [a]
xs \\ ys = filter (\x -> x `notElem` ys) xs

-- Minfree checklist

minfree_chl :: [Int] -> Int
minfree_chl = search . checklist

search :: Array Int Bool -> Int
search = length . takeWhile id . elems

checklist :: [Int] -> Array Int Bool
checklist xs = accumArray (||) False (0,n)
                (zip (filter (<=n) xs) (repeat True))
                where n = length xs
         
-- minfree countlist
       
minfree_col :: [Int] -> Int
minfree_col = search0 . assocs . countlist

countlist :: [Int] -> Array Int Int
countlist xs = accumArray (+) 0 (0,n) (zip xs (repeat 1))
  where n = length xs
  
sort :: [Int] -> [Int]
sort xs = concat [replicate k x | (x,k) <- assocs $ countlist xs]

search0 :: [(Int, Int)] -> Int
search0 [] = -1
search0((i,0):_) = i
search0 (x:xs) = search0 xs

-- minfree basic daq

minfree_b :: [Int] -> Int
minfree_b xs = if (null ([0..b-1] \\ us))
    then (head ([b..] \\ vs))
    else (head ([0..] \\ us))
    where
      b = 1 + (length xs) `div` 2
      (us, vs) = partition (<b) xs
      
-- minfree refined daq

minfree_r :: [Int] -> Int
minfree_r = minfrom_r 0

minfrom_r :: Nat -> [Nat] -> Nat
minfrom_r a xs
  | null xs   = a
  | length us == b-a =  minfrom_r b vs
  | otherwise = minfrom_r b us
  where 
    b = a + 1 + (length xs) `div` 2
    (us, vs) = partition (<b) xs

-- minfree optimized daq (p262)
    
minfree_o :: [Int] -> Int
minfree_o xs = minfrom_o 0 (length xs, xs)

minfrom_o :: Int -> (Int, [Int]) -> Int
minfrom_o a (n, xs)
  | n == 0    = a
  | m == b-a  = minfrom_o b (n-m, vs)
  | otherwise = minfrom_o a (m, us)
  where
    (us,vs) = partition (<b) xs
    b       = a + 1 + n `div` 2
    m       = length us
    
-- true daq implementations

divideAndConquer :: (p->Bool) -> (p->s) ->(p-> [p]) -> (p-> [s] -> s)-> p -> s
divideAndConquer indiv solve divide combine initPb = dAC initPb
  where 
    dAC pb
      | indiv pb  = solve pb
      | otherwise = combine pb (map dAC (divide pb))
      
-- minfree basic daq higher order

b_indiv :: Int -> [Int] -> Bool
b_indiv l xs = length xs < l

b_solve :: [Int] -> [Int]
b_solve = id

b_divide :: Int -> [Int] -> [[Int]]
b_divide b xs = [us, vs]
  where (us,vs) = partition (<b) xs
  
b_combine :: Int -> [Int] -> [[Int]] -> [Int]
b_combine b _ (us:vs:[]) = if (null ([0..b-1] \\ us))
    then ([b..] \\ vs)
    else ([0..] \\ us)
  
minfree_bhof :: [Int] -> Int
minfree_bhof xs = head $ divideAndConquer (b_indiv (length xs)) b_solve (b_divide b) (b_combine b) xs
  where b = 1+(length xs) `div` 2
  
-- minfree refined daq higher order