Advertisement
ptrelford

Potter Kata in F#

Oct 11th, 2014
366
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 1.32 KB | None | 0 0
  1. // Potter Kata: http://codingdojo.org/cgi-bin/index.pl?KataPotter
  2.  
  3. [<Measure>] type EUR
  4.  
  5. let bookPrice = 8M<EUR>
  6.  
  7. let priceOfSeries = function
  8.    | 1 -> bookPrice
  9.    | 2 -> 2M * bookPrice * 0.95M
  10.    | 3 -> 3M * bookPrice * 0.90M
  11.    | 4 -> 4M * bookPrice * 0.80M
  12.    | 5 -> 5M * bookPrice * 0.75M
  13.    | n -> invalidOp (sprintf "Invalid set of %d" n)
  14.    
  15. let priceOfSets = Seq.sumBy (Set.count >> priceOfSeries)
  16.  
  17. let canAdd book series = series |> Set.contains book |> not  
  18.  
  19. let computeValidAdditions book sets =
  20.    let rec compute front = function
  21.       | [] -> []
  22.       | head::tail ->
  23.          let newFront = head::front
  24.          if canAdd book head
  25.          then
  26.             let newSeries = Set.add book head
  27.             let validSet = newSeries::front@tail
  28.             validSet :: compute newFront tail
  29.          else compute newFront tail
  30.    sets |> compute []
  31.    
  32. let toSets books =
  33.    books |> Seq.fold (fun sets book ->
  34.       let additions = computeValidAdditions book sets
  35.       let newSets =
  36.          if additions.Length = 0
  37.          then [set [book]::sets]
  38.          else additions      
  39.       newSets
  40.       |> List.map (fun sets -> sets, priceOfSets sets)
  41.       |> List.minBy snd
  42.       |> fst    
  43.    ) [Set.empty]
  44.  
  45. toSets [0;0;1;1;2;2;3;4;]
  46. |> priceOfSets
  47. // val it : decimal<EUR> = 51.20M
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement