diff options
| author | manuel <manuel@mausz.at> | 2012-05-13 18:59:03 +0200 |
|---|---|---|
| committer | manuel <manuel@mausz.at> | 2012-05-13 18:59:03 +0200 |
| commit | a41901074761845d456d629f1f5a38d0e0e2a6c3 (patch) | |
| tree | 30b4a09bf6e164ff996cce4da430cf08ea3477f8 | |
| parent | 0c6db49a47e84bf9c2c014446bf666d446c058f3 (diff) | |
| parent | 3cc0356cae5bc03e2331a68c3411e3df7cd222d6 (diff) | |
| download | ffp-a41901074761845d456d629f1f5a38d0e0e2a6c3.tar.gz ffp-a41901074761845d456d629f1f5a38d0e0e2a6c3.tar.bz2 ffp-a41901074761845d456d629f1f5a38d0e0e2a6c3.zip | |
Merge branch 'master' of ssh://git.manuel.mausz.at:2211/ffp
| -rw-r--r-- | AufgabeFFP5.hs | 118 | ||||
| -rw-r--r-- | AufgabeFFP6.pdf | bin | 0 -> 37916 bytes | |||
| -rw-r--r-- | TestAufgabeFFP5.hs | 70 |
3 files changed, 188 insertions, 0 deletions
diff --git a/AufgabeFFP5.hs b/AufgabeFFP5.hs new file mode 100644 index 0000000..75383f7 --- /dev/null +++ b/AufgabeFFP5.hs | |||
| @@ -0,0 +1,118 @@ | |||
| 1 | module AufgabeFFP5 | ||
| 2 | where | ||
| 3 | |||
| 4 | import Data.Array | ||
| 5 | |||
| 6 | newtype Table a b = Tbl (Array b a) | ||
| 7 | deriving Show | ||
| 8 | |||
| 9 | newTable :: (Ix b) => [(b, a)] -> Table a b | ||
| 10 | newTable l = Tbl (array (lo, hi) l) | ||
| 11 | where | ||
| 12 | indices = map fst l | ||
| 13 | lo = minimum indices | ||
| 14 | hi = maximum indices | ||
| 15 | |||
| 16 | findTable :: (Ix b) => Table a b -> b -> a | ||
| 17 | findTable (Tbl a) i = a ! i | ||
| 18 | |||
| 19 | updTable :: (Ix b) => (b, a) -> Table a b -> Table a b | ||
| 20 | updTable p@(i, x) (Tbl a) = Tbl (a // [p]) | ||
| 21 | |||
| 22 | dynamic :: (Ix coord) => (Table entry coord -> coord -> entry) -> (coord, coord) -> (Table entry coord) | ||
| 23 | dynamic compute bnds = t | ||
| 24 | where | ||
| 25 | t = newTable (map (\coord -> (coord, compute t coord)) (range bnds)) | ||
| 26 | |||
| 27 | ------------------------------------------------------------------------------- | ||
| 28 | -- 1. | ||
| 29 | ------------------------------------------------------------------------------- | ||
| 30 | |||
| 31 | bndsAS :: Array Int Int -> ((Int, Int), (Int, Int)) | ||
| 32 | bndsAS a = ((l,l), (h,h)) | ||
| 33 | where | ||
| 34 | (l,h) = bounds a | ||
| 35 | |||
| 36 | -- fill the table. Lower half below diagonal not necessary | ||
| 37 | -- but filled with the symmetric value | ||
| 38 | compAS :: Array Int Int -> Table Int (Int, Int) -> (Int, Int) -> Int | ||
| 39 | compAS a t (i,j) | ||
| 40 | | i == j = a ! j | ||
| 41 | | i<j = compAS a t (j,i) | ||
| 42 | | otherwise = findTable t (i-1, j) + a!i | ||
| 43 | |||
| 44 | -- computes distance-sum-table for array | ||
| 45 | asTbl :: Array Int Int -> Table Int (Int, Int) | ||
| 46 | asTbl a = dynamic (compAS a) (bndsAS a) | ||
| 47 | |||
| 48 | -- maximum function for tables | ||
| 49 | tblMax :: (Ord a, Ix b) => Table a b -> a | ||
| 50 | tblMax (Tbl a) = maximum $ elems a | ||
| 51 | |||
| 52 | -- maximum of the array's distance-sums | ||
| 53 | mas :: Array Int Int -> Int | ||
| 54 | mas a = tblMax $ asTbl a | ||
| 55 | |||
| 56 | ------------------------------------------------------------------------------- | ||
| 57 | -- 2. | ||
| 58 | ------------------------------------------------------------------------------- | ||
| 59 | |||
| 60 | -- all indices where the value equals to the maximum distance-sum | ||
| 61 | amas :: Array Int Int -> [(Int, Int)] | ||
| 62 | amas a = [(i,j) | ((i,j),v) <- (assocs array), i<=j, v>=maxAS] | ||
| 63 | where | ||
| 64 | t@(Tbl array) = asTbl a | ||
| 65 | maxAS = tblMax t | ||
| 66 | |||
| 67 | ------------------------------------------------------------------------------- | ||
| 68 | -- 3. | ||
| 69 | ------------------------------------------------------------------------------- | ||
| 70 | |||
| 71 | -- computes index with maximum index-difference | ||
| 72 | maxL :: [(Int, Int)] -> (Int, Int) | ||
| 73 | maxL [] = error "maximum of empty list" | ||
| 74 | maxL [x] = x | ||
| 75 | maxL (x:xs) | ||
| 76 | | l x >= l maxTail = x | ||
| 77 | | otherwise = maxTail | ||
| 78 | where | ||
| 79 | l (x,y) = y-x | ||
| 80 | maxTail = maxL xs | ||
| 81 | |||
| 82 | -- index with maximum distance-sum and maximum index-difference | ||
| 83 | lmas :: Array Int Int -> (Int, Int) | ||
| 84 | lmas a = maxL $ amas a | ||
| 85 | |||
| 86 | ------------------------------------------------------------------------------- | ||
| 87 | |||
| 88 | divideAndConquer :: (p->Bool) -> (p->s) -> (p->[p]) -> (p->[s]->s) -> p -> s | ||
| 89 | divideAndConquer indiv solve divide combine initPb = dAC initPb | ||
| 90 | where | ||
| 91 | dAC pb | ||
| 92 | | indiv pb = solve pb | ||
| 93 | | otherwise = combine pb (map dAC (divide pb)) | ||
| 94 | |||
| 95 | |||
| 96 | ------------------------------------------------------------------------------- | ||
| 97 | -- 4. | ||
| 98 | ------------------------------------------------------------------------------- | ||
| 99 | |||
| 100 | mi_indiv :: [a] -> Bool | ||
| 101 | mi_indiv a = length a <= 1 | ||
| 102 | |||
| 103 | mi_solve :: (Ix a, Show a) => (b -> Bool) -> [(a,b)] -> [(a,b)] | ||
| 104 | mi_solve wf [(a,b)] | ||
| 105 | | wf b = [(a,b)] | ||
| 106 | | otherwise = [] | ||
| 107 | |||
| 108 | mi_divide :: [a] -> [[a]] | ||
| 109 | mi_divide (x:xs) = [[x], xs] | ||
| 110 | |||
| 111 | mi_combine :: [a] -> [[a]] -> [a] | ||
| 112 | mi_combine _ [] = error "No matching index" | ||
| 113 | mi_combine a (x:xs) | ||
| 114 | | null x = mi_combine a xs | ||
| 115 | | otherwise = [head x] | ||
| 116 | |||
| 117 | minIndex :: (Ix a, Show a) => Array a b -> (b -> Bool) -> a | ||
| 118 | minIndex a wf = fst $ head $ divideAndConquer mi_indiv (mi_solve wf) mi_divide mi_combine $ assocs a | ||
diff --git a/AufgabeFFP6.pdf b/AufgabeFFP6.pdf new file mode 100644 index 0000000..0fe111b --- /dev/null +++ b/AufgabeFFP6.pdf | |||
| Binary files differ | |||
diff --git a/TestAufgabeFFP5.hs b/TestAufgabeFFP5.hs new file mode 100644 index 0000000..865f503 --- /dev/null +++ b/TestAufgabeFFP5.hs | |||
| @@ -0,0 +1,70 @@ | |||
| 1 | module Main where | ||
| 2 | |||
| 3 | import Test.HUnit | ||
| 4 | import Control.Monad | ||
| 5 | import Data.Array | ||
| 6 | import AufgabeFFP5 | ||
| 7 | |||
| 8 | a :: Array Int Int | ||
| 9 | a = array (1,9) [(1,3),(2,(-5)),(3,0),(4,9),(5,2),(6,(-1)),(7,2),(8,(-5)),(9,1)] | ||
| 10 | |||
| 11 | b :: Array Int Int | ||
| 12 | b = array (1,9) [(1,3),(2,(-1)),(3,(-2)),(4,9),(5,2),(6,(-1)),(7,2),(8,0),(9,(-1))] | ||
| 13 | |||
| 14 | c :: Array Int Int | ||
| 15 | c = array (1,5) [(1,2),(2,3),(3,(-10)),(4,1),(5,4)] | ||
| 16 | |||
| 17 | d :: Array Int Int | ||
| 18 | d = array (1,6) [(1, (-3)), (2, 1), (3, 10), (4, (-5)), (5, 8), (6, 7)] | ||
| 19 | |||
| 20 | minA :: Array Int Int | ||
| 21 | minA = array (0,0) [(0,0)] | ||
| 22 | |||
| 23 | data Week = Mon | Tue | Wed | Thu | Fri | Sat | Sun deriving (Eq, Ord, Ix, Show) | ||
| 24 | |||
| 25 | w :: Array Week String | ||
| 26 | w = array (Tue, Sat) [(Wed, "work"), (Thu, "study"), (Tue, "study"), (Fri, "chill"), (Sat, "relax")] | ||
| 27 | |||
| 28 | cases1 = "mas" ~: TestList [ | ||
| 29 | "mas a" ~: 12 ~=? (mas a), | ||
| 30 | "mas b" ~: 12 ~=? (mas b), | ||
| 31 | "mas c" ~: 5 ~=? (mas c), | ||
| 32 | "mas d" ~: 21 ~=? (mas d), | ||
| 33 | "mas minA" ~: 0 ~=? (mas minA) | ||
| 34 | ] | ||
| 35 | |||
| 36 | cases2 = TestLabel "amas" $ TestList [ | ||
| 37 | "amas a" ~: [(3,7), (4,7)] ~=? (amas a), | ||
| 38 | "amas b" ~: [(1,7),(1,8),(4,7),(4,8)] ~=? (amas b), | ||
| 39 | "amas c" ~: [(1,2),(4,5)] ~=? (amas c), | ||
| 40 | "amas d" ~: [(2,6)] ~=? (amas d), | ||
| 41 | "amas minA" ~: [(0,0)] ~=? (amas minA) | ||
| 42 | ] | ||
| 43 | |||
| 44 | cases3 = TestLabel "lmas" $ TestList [ | ||
| 45 | "lmas a" ~: (3,7) ~=? (lmas a), | ||
| 46 | "lmas b" ~: (1,8) ~=? (lmas b), | ||
| 47 | "lmas c" ~: (1,2) ~=? (lmas c), | ||
| 48 | "lmas d" ~: (2,6) ~=? (lmas d), | ||
| 49 | "lmas minA" ~: (0,0) ~=? (lmas minA) | ||
| 50 | ] | ||
| 51 | |||
| 52 | cases4 = TestLabel "minIndex" $ TestList [ | ||
| 53 | "minIndex a (>5)" ~: 4 ~=? (minIndex a (>5)), | ||
| 54 | "minIndex a (<0)" ~: 2 ~=? (minIndex a (<0)), | ||
| 55 | "minIndex a (even)" ~: 3 ~=? (minIndex a (even)), | ||
| 56 | "minIndex b (odd)" ~: 1 ~=? (minIndex b (odd)), | ||
| 57 | -- "minIndex b (>100)" ~: error "No matching index" ~=? (minIndex b (>100)), | ||
| 58 | "minIndex w (=='relax')" ~: Sat ~=? (minIndex w (=="relax")), | ||
| 59 | "minIndex w (=='work')" ~: Wed ~=? (minIndex w (=="work")), | ||
| 60 | "minIndex w (=='chill')" ~: Fri ~=? (minIndex w (=="chill")), | ||
| 61 | "minIndex w (/='chill')" ~: Tue ~=? (minIndex w (/="chill")) | ||
| 62 | -- "minIndex w (=='swim')" ~: error "No matching index" ~=? (minIndex w (=="swim")) | ||
| 63 | ] | ||
| 64 | |||
| 65 | tests :: [Test] | ||
| 66 | tests = [cases1, cases2, cases3, cases4] | ||
| 67 | |||
| 68 | main = do | ||
| 69 | forM tests $ \test -> | ||
| 70 | runTestTT test | ||
