Created
December 13, 2015 13:18
-
-
Save ygrenzinger/ddc01b3900c1c7a04e46 to your computer and use it in GitHub Desktop.
Solution for problem of Edx F# Module 4
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
open System | |
open System.IO | |
type Shot = | |
{ X : float | |
Y : float | |
Speed : float | |
ExpectedDistance : float | |
Name : string } | |
type ShotStatus = Hit|Miss|TooFar | |
type ShotResult = | |
{ Status : ShotStatus | |
Angle : float | |
Name : string } | |
let gravity = 9.81 | |
let fire shot = | |
let { X = x; Y = y; Speed = speed; ExpectedDistance = expectedDistance; Name = name } = shot | |
let speed2 = Math.Pow(speed,2.0); | |
let maxDistance = speed2 / gravity | |
let theta = Math.Atan(y / x) | |
let angleOfReach = 0.5 * Math.Asin((gravity * expectedDistance) / speed2) | |
let distanceTravelled = (speed2 * Math.Sin(2.0 * theta)) / gravity | |
let status = | |
if (expectedDistance > maxDistance) then ShotStatus.TooFar | |
elif (distanceTravelled = expectedDistance) then ShotStatus.Hit | |
else ShotStatus.Miss | |
let result = { Status = status; Angle = angleOfReach; Name = name } | |
result | |
let result shot = | |
match fire shot with | |
| { ShotResult.Status = status; ShotResult.Angle = angle; ShotResult.Name = name } | |
when status = ShotStatus.TooFar -> sprintf "%s has missed. Distance out of reach." name | |
| { ShotResult.Status = status; ShotResult.Angle = angle; ShotResult.Name = name } | |
when status = ShotStatus.Hit -> sprintf "%s is a hit!" name | |
| { ShotResult.Status = status; ShotResult.Angle = angle; ShotResult.Name = name } | |
when status = ShotStatus.Miss -> sprintf "%s has missed. Angle of reach needed was %f." name angle | |
| _ -> "" | |
let GetFile = | |
let mutable filepath = "" | |
while filepath = "" do | |
Console.Write("Enter the full path to the name of the input file: ") | |
filepath <- Console.ReadLine() | |
filepath | |
[<EntryPoint>] | |
let main argv = | |
try | |
use input = | |
new StreamReader(match argv.Length with | |
| 0 -> GetFile | |
| _ -> argv.[0]) | |
let shots = | |
[ while not input.EndOfStream do | |
let raw = input.ReadLine() | |
let values = raw.Split(',') | |
yield { X = float values.[0] | |
Y = float values.[1] | |
Speed = float values.[2] | |
ExpectedDistance = float values.[3] | |
Name = values.[4] } ] | |
Console.WriteLine("The shots fired were: ") | |
for e in shots do | |
Console.WriteLine(result e) | |
let c = Console.ReadKey() | |
0 // return an integer exit code | |
with | |
| :? System.IO.FileNotFoundException -> | |
-1 | |
| _ -> | |
-1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment