diff options
| -rw-r--r-- | AufgabeFFP3.hs | 71 | ||||
| -rw-r--r-- | TestAufgabeFFP3.hs | 24 |
2 files changed, 95 insertions, 0 deletions
diff --git a/AufgabeFFP3.hs b/AufgabeFFP3.hs new file mode 100644 index 0000000..67519be --- /dev/null +++ b/AufgabeFFP3.hs | |||
| @@ -0,0 +1,71 @@ | |||
| 1 | module AufgabeFFP3 | ||
| 2 | where | ||
| 3 | |||
| 4 | import Prelude hiding (filter) | ||
| 5 | |||
| 6 | type Weight = Int | ||
| 7 | type Value = Int | ||
| 8 | type Item = (Weight, Value) | ||
| 9 | type Items = [Item] | ||
| 10 | |||
| 11 | type Load = [Item] | ||
| 12 | |||
| 13 | type Loads = [Load] | ||
| 14 | type LoadWghtVal = (Load, Weight, Value) | ||
| 15 | type MaxWeight = Weight | ||
| 16 | |||
| 17 | safeGet :: [Integer] -> Int -> Integer -- get element of list, default to 0 | ||
| 18 | safeGet l i | ||
| 19 | | i < length l = l !! i | ||
| 20 | | otherwise = 0 | ||
| 21 | |||
| 22 | toBin :: Integer -> [Integer] -- get binary representation of integer | ||
| 23 | toBin 0 = [] | ||
| 24 | toBin i = [rem] ++ toBin quot | ||
| 25 | where ( quot, rem ) = quotRem i 2 | ||
| 26 | |||
| 27 | hasBit :: Integer -> Int -> Bool -- check if the binary representation of a number has the ith bit set | ||
| 28 | hasBit num ith = (safeGet (toBin num) ith) == 1 | ||
| 29 | |||
| 30 | getChoice :: Items -> Int -> Items -- choose a subset determined by binary representation of l | ||
| 31 | getChoice l i = concat ( map (choose l) [0..(length l)-1] ) | ||
| 32 | where | ||
| 33 | choose l pos | ||
| 34 | | hasBit (fromIntegral i) pos = [ l !! pos ] | ||
| 35 | | otherwise = [] | ||
| 36 | |||
| 37 | generator:: Items -> Loads -- get all possible choices (2^n) | ||
| 38 | generator l = map ( getChoice l ) [1..num] | ||
| 39 | where num = (2^(length l)) - 1 | ||
| 40 | |||
| 41 | transformer :: Loads -> [LoadWghtVal] -- calc sum of weight and value for all lists of items | ||
| 42 | transformer l = map trans l | ||
| 43 | |||
| 44 | trans :: Load -> LoadWghtVal -- worker of transformer | ||
| 45 | trans load = (load, weight, value) | ||
| 46 | where | ||
| 47 | weight = sum $ map fst load | ||
| 48 | value = sum $ map snd load | ||
| 49 | |||
| 50 | getWeight :: LoadWghtVal -> Weight | ||
| 51 | getWeight (_, w, _) = w | ||
| 52 | |||
| 53 | getVal :: LoadWghtVal -> Value | ||
| 54 | getVal (_, _, v) = v | ||
| 55 | |||
| 56 | filter :: MaxWeight -> [LoadWghtVal] -> [LoadWghtVal] -- drop those with too much weight | ||
| 57 | filter max l = [ x | x <- l, getWeight x <= max ] | ||
| 58 | |||
| 59 | selector :: [LoadWghtVal] -> [LoadWghtVal] -- get those with max val | ||
| 60 | selector l = [ x | x <- l, getVal x == max ] | ||
| 61 | where max = maximum $ map getVal l | ||
| 62 | |||
| 63 | selector1 :: [LoadWghtVal] -> [LoadWghtVal] -- all with max val | ||
| 64 | selector1 = selector | ||
| 65 | |||
| 66 | selector2 :: [LoadWghtVal] -> [LoadWghtVal] -- get ones with min weight | ||
| 67 | selector2 l = [ x | x <- best, getWeight x == min ] | ||
| 68 | where | ||
| 69 | min = minimum $ map getWeight best | ||
| 70 | best = selector l | ||
| 71 | |||
diff --git a/TestAufgabeFFP3.hs b/TestAufgabeFFP3.hs new file mode 100644 index 0000000..bbb5fbc --- /dev/null +++ b/TestAufgabeFFP3.hs | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | module Main where | ||
| 2 | |||
| 3 | import Prelude hiding (filter) | ||
| 4 | |||
| 5 | |||
| 6 | import Test.HUnit | ||
| 7 | import Control.Monad | ||
| 8 | import AufgabeFFP3 | ||
| 9 | |||
| 10 | cases1 = TestLabel "foo" $ TestList [ | ||
| 11 | TestCase $ assertEqual "a" [([(2,7),(2,6)],4,13)] ((selector1 . (filter 5) . transformer . generator) [(5,3),(2,7),(2,6),(10,100)]), | ||
| 12 | TestCase $ assertEqual "b" ((selector1 . (filter 13) . transformer . generator) [(5,3),(2,7),(2,6),(10,100)]) [([(2,7),(10,100)],12,107)], | ||
| 13 | TestCase $ assertEqual "c" ((selector1 . (filter 1) . transformer . generator) [(5,3),(2,7),(2,6),(10,100)]) [], | ||
| 14 | TestCase $ assertEqual "d" ((selector1 . (filter 5) . transformer . generator) [(5,13),(2,7),(2,6),(10,100)]) [([(5,13)],5,13), ([(2,7),(2,6)],4,13)], | ||
| 15 | TestCase $ assertEqual "e" ((selector2 . (filter 5) . transformer . generator) [(5,13),(2,7),(2,6),(10,100)]) [([(2,7),(2,6)],4,13)] | ||
| 16 | ] | ||
| 17 | |||
| 18 | tests :: [Test] | ||
| 19 | tests = [cases1] | ||
| 20 | |||
| 21 | main = do | ||
| 22 | forM tests $ \test -> | ||
| 23 | runTestTT test | ||
| 24 | |||
