import Maybe


-- Aufgabe 16

-- (a) [[10],[9],[8],[7],[6],[5],[4],[3],[2],[1]]
a = [ [11-x] | x <- [1..10] ]

-- (b) [(5,False),(10,True),(15,False),(40,False)]
b = [ (x*5,y) | x <- [1..10], y <- [True,False]
              , (x==2 && y==True) || ((x==1 || x==3 || x==8) && y==False) ]

-- (c) [(11,12),(13,14),(15,16),(17,18),(19,20)]
c = [ (x+10,x+11) | x <- [1..10], mod x 2 == 1 ]

-- (d) [[4],[6,4],[8,6,4],[10,8,6,4],[12,10,8,6,4]]
d = [ [2*x,2*x-1..3] | x <- [1..10], 1 < x, x < 7 ]

-- (e) [[5,6,7],[5,6,7,8,9],[5,6,7,8,9,10,11],[5,6,7,8,9,10,11,12,13]]
e = [ [5..x+5] | x<- [1..10], x < 10, even x ]

-- (f) [1,1,2,1,2,3,1,2,3,4]
f = [ y | x <- [1..10], x < 5, y <- [1..x] ]

maP f xs = [ f x | x <- xs ]

lookuP x xys = listToMaybe [ y | (x',y) <- xys, x==x' ]

replicatE n x = [ x | _ <- [1..n] ]

filteR p xs = [ x | x <- xs, p x ]


-- Aufgabe 17

dc :: (problem -> Bool)                  -- trivialer Fall? 
   -> (problem -> [problem])             -- aufteilen in Teilprobleme
   -> (problem -> solution)              -- Loesen von trivialen Problemen
   -> (solution -> solution -> solution) -- Kombination von Teilloesungen
   -> problem                            -- Problem
   -> solution                           -- Loesung
dc trivial divide solve combine problem
  | trivial problem = solve problem
  | otherwise = foldr1 combine $ map conquer $ divide problem
 where
  conquer = dc trivial divide solve combine


quickSort :: Ord a => [a] -> [a]
quickSort = dc trivial divide solve combine
 where
  trivial xs = length xs <= 1
  divide (x:xs) = [filter (<x) xs, [x], filter (>=x) xs]
  solve xs = xs
  combine xs ys = xs ++ ys 


-- Aufgabe 18

data Question = Free String | Choice String [String]
 deriving (Eq,Show)

data Answer = FreeAnswer String | ChoiceAnswer Int
 deriving (Eq,Show)

questionary :: [Question] -> IO [Answer]
questionary [] = return []

questionary (Free q:qs) = do
  putStr q
  putStr ": "
  freeAnswer <- getLine
  answers <- questionary qs
  return (FreeAnswer freeAnswer : answers)

questionary (Choice q xs : qs) = do
  putStr (q++" ("++ showAlternatives (zip [1..] xs) ++"): ")
  choiceAnswer <- getLine
  answers <- questionary qs
  return (ChoiceAnswer (read choiceAnswer) : answers)

-- keine Fehlerbehandlung!

showAlternatives :: [(Int,String)] -> String
showAlternatives = foldr1 (\x y -> x++"/"++y) . map (\ (n,x) -> show n++"."++x)

main =
  questionary [Free "Name", Choice "Geschlecht" ["weiblich","maennlich"]]
  >>= print


