Advertisement
olemis

Edx - F# - Patterns

Nov 14th, 2015
224
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 4.99 KB | None | 0 0
  1. // Learn more about F# at http://fsharp.org
  2. // See the 'F# Tutorial' project for more help.
  3.  
  4. // Link to Solution can be found here - http://xxx
  5.  
  6. type MyRecord = {
  7.         IP : string
  8.         MAC : string
  9.         FriendlyName : string
  10.         ID : int }
  11.  
  12. type GunState =
  13.     {
  14.         X: double
  15.         Y: double
  16.         Speed: double
  17.         ExpectedDistance: double
  18.         Name: string
  19.     }
  20.  
  21. type ShotResult =
  22. | ShotSuccess
  23. | ShotFailure of double
  24. | ShotImpossible
  25.  
  26. type GunResult =
  27.     {
  28.         Name: string
  29.         Result: ShotResult
  30.     }
  31.  
  32. open System
  33. open System.IO
  34.  
  35. [<EntryPoint>]
  36. let main argv =
  37.  
  38.     // Koan
  39.  
  40. //    type MyRecord =
  41. //        { IP : string
  42. //          MAC : string
  43. //          FriendlyName : string
  44. //          ID : int }
  45. //
  46. //    let IsMatchByName record1 name =
  47. //        match record with
  48. //        | { FriendlyName = nameFound; ID = _; IP = _ } if nameFound = name yield Some((id,ip))
  49. //        | _ -> None  
  50. //
  51. //    let checkmatch input =
  52. //        match input with
  53. //        | x, y -> printfn "%A" x  
  54. //        | None -> printfn "%A" "Sorry no match"  
  55.  
  56.     let IsMatchByName record name =
  57.         match record with
  58.         | { FriendlyName = nameFound; ID = _; IP = _ } -> if nameFound = name then Some((record.ID, record.IP))
  59.                                                           else None
  60.         | _ -> None  
  61.  
  62.     let checkmatch input =
  63.         match input with
  64.         | Some((x, y)) -> printfn "%A" x  
  65.         | None -> printfn "%A" "Sorry no match"  
  66.  
  67. //    let record = {IP ="127.0.0.1"; MAC ="FF:FF:FF:FF:FF:FF"; FriendlyName = "Home";ID = 229229}
  68.     let record = {IP = "10.1.1.1"; MAC = "FF:FF:FF:FF:FF:FF"; FriendlyName = "ServerFailure";ID = 0}
  69.  
  70.     printf "Enter name "
  71.     let name = Console.ReadLine()
  72.  
  73.     let m = IsMatchByName record name
  74.     checkmatch m
  75.  
  76.     // Problem
  77.  
  78.     let angle_of_reach d v =
  79.         let x = 9.81 * d / Math.Pow(v, 2.0)
  80.         if Math.Abs(x) <= 1.0 then
  81.             Some (0.5 * Math.Asin(x))
  82.         else
  83.             None
  84.     let distance_travelled angle v = Math.Pow(v, 2.0) * Math.Sin(2.0 * angle) / 9.81
  85.     let angle x y = Math.Atan(y / x)
  86.  
  87.     let GetFile =
  88.         Console.Write("Enter the full path to the name of the input file: ")
  89.         Console.ReadLine()
  90.     try
  91.         use input =
  92.             new StreamReader(match argv.Length with
  93.                              | 0 -> GetFile    
  94.                              | _ -> argv.[0])
  95.         // By using sequences file and memory access will be efficient
  96.         let data = seq {while not input.EndOfStream do
  97.                             let raw = input.ReadLine()
  98.                             let values = raw.Split(',')
  99.                             yield {
  100.                                     X = double values.[0]
  101.                                     Y = double values.[1]
  102.                                     Speed = double values.[2]
  103.                                     ExpectedDistance = double values.[3]
  104.                                     Name = values.[4]
  105.                                 }
  106.                         }
  107.         let results = seq {
  108.                             // Correction factor to deal with
  109.                             // accumulated floating point errors
  110.                             let epsilon = 0.005
  111.                             for gun in data do
  112.                                 let angle = Math.Atan2(gun.Y, gun.X)
  113.                                 let d = distance_travelled angle gun.Speed
  114.                                 if Math.Abs(d - gun.ExpectedDistance) < epsilon then
  115.                                     yield {
  116.                                             Name = gun.Name
  117.                                             Result = ShotSuccess
  118.                                           }
  119.                                 else
  120.                                     yield {
  121.                                         Name = gun.Name
  122.                                         Result = match angle_of_reach gun.ExpectedDistance gun.Speed with
  123.                                                  | Some expected_angle -> ShotFailure expected_angle
  124.                                                  | None                -> ShotImpossible
  125.                                         }
  126.                             }
  127.         for r in results do
  128.             let msg =
  129.                 match r.Result with
  130.                 | ShotFailure expected_angle -> "failed since angle should be " + expected_angle.ToString()
  131.                 | ShotSuccess _                       -> "hits the target"
  132.                 | ShotImpossible                      -> "target is too far"
  133.             printfn "Gun %s %s" r.Name msg
  134.         Console.ReadKey()
  135.         0
  136.     with
  137.         | :? System.IO.FileNotFoundException ->
  138.             Console.Write("File Not Found. Press a key to exit")
  139.             Console.ReadKey()
  140.             -1
  141.         | _ ->
  142.             Console.Write("Something else happened")
  143.             Console.ReadKey()
  144.             -1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement