Advertisement
Guest User

storeCredit.hs

a guest
Jul 9th, 2014
319
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import Data.Char(digitToInt)
  2. import Text.Printf
  3.  
  4. -- Input => solver => output.
  5. main = interact (unlines . solve . lines)
  6.  
  7. -- Ignore the first line of input (number of test cases).
  8. solve (_:xs) = solveaux xs 1
  9.  
  10. -- Parse the input to the Int and Lists, pass those values to the actual algorithm and parse the solution to a list
  11. -- of strings.
  12. solveaux :: [String] -> Int -> [String]
  13. solveaux [] _ = []
  14. solveaux (credit:_:items: xs) idx =
  15.     (strSelectedItems (read credit :: Int) $ parseItems items) : solveaux xs (idx + 1)
  16.     where strSelectedItems c is = toResult (selectedItems c is) idx
  17.  
  18. -- I could, and probably should, put this in the were clause of the solveaux function.
  19. toResult :: (Int, Int) -> Int -> String
  20. toResult (x,y) i = printf "Case #%d: %d %d" i x y
  21.  
  22. -- The actual algorithm for the problem.
  23. selectedItems :: Int -> [Int] -> (Int, Int)
  24. selectedItems cred items =
  25.     select cred $ comb 2 [1..(length items)]
  26.     where select c [] = (1,1)
  27.           select c ([i1, i2]:ps) = if ((items !! (i1-1)) + items !! (i2-1)) == c
  28.                                    then (i1, i2)
  29.                                    else select c ps
  30.  
  31. -- There are a few other ways to implement this in http://rosettacode.org/wiki/Combinations#Haskell
  32. -- but this one seemed to be the most straight forward.
  33. comb :: Int -> [a] -> [[a]]
  34. comb 0 _      = [[]]
  35. comb _ []     = []
  36. comb m (x:xs) = map (x:) (comb (m-1) xs) ++ comb m xs
  37.  
  38. -- "1 2 3" => [1,2,3]
  39. parseItems :: String -> [Int]
  40. parseItems is = map readint (words is)
  41.     where readint x = read x :: Int
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement