Last active
June 9, 2021 11:21
-
-
Save tonymorris/cba069d3666bed134b67b029a118c848 to your computer and use it in GitHub Desktop.
This file contains 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
#!/usr/bin/env runhaskell | |
{-# LANGUAGE DeriveFunctor #-} | |
{-# LANGUAGE DeriveFoldable #-} | |
import Data.Foldable | |
import Text.Printf | |
data Point a = | |
Point { | |
x :: a | |
, y :: Int | |
} deriving (Eq, Ord, Show, Functor) | |
-- BEGIN: given by LOADING ECHO | |
forward_limit1 :: | |
Num a => | |
Point a | |
forward_limit1 = | |
Point 2400 2000 | |
forward_limit2 :: | |
Num a => | |
Point a | |
forward_limit2 = | |
Point 2400 2360 | |
forward_limit3 :: | |
Num a => | |
Point a | |
forward_limit3 = | |
Point 2560 2950 | |
aft_limit1 :: | |
Num a => | |
Point a | |
aft_limit1 = | |
Point 2680 2000 | |
aft_limit2 :: | |
Num a => | |
Point a | |
aft_limit2 = | |
Point 2680 2950 | |
aux_tank_arm = | |
2800 | |
-- END: given by LOADING ECHO | |
iu :: | |
Fractional a => | |
Point a | |
-> Point a | |
iu (Point x y) = | |
Point (fromIntegral y * x / 10000) y | |
data Line x y = | |
Line (Point x) (Point y) | |
deriving (Eq, Ord, Show) | |
gradient :: | |
Fractional a => | |
Line a a | |
-> a | |
gradient (Line (Point x1 y1) (Point x2 y2)) = | |
let y' = y2 - y1 | |
in if y' == 0 then 0 else (x2 - x1) / fromIntegral y' | |
data Five a = | |
Five { | |
a1 :: a | |
, a2 :: a | |
, a3 :: a | |
, a4 :: a | |
, a5 :: a | |
} | |
deriving (Eq, Ord, Show, Functor, Foldable) | |
instance Applicative Five where | |
pure a = | |
Five a a a a a | |
Five f1 f2 f3 f4 f5 <*> Five a1 a2 a3 a4 a5 = | |
Five (f1 a1) (f2 a2) (f3 a3) (f4 a4) (f5 a5) | |
pairFive (Five a1 a2 a3 a4 a5) = | |
Five (a1, a2) (a2, a3) (a3, a4) (a4, a5) (a5, a1) | |
type Polygon5 a = | |
Five (Point a) | |
echoPoints :: | |
Polygon5 Double | |
echoPoints = | |
iu <$> | |
Five | |
forward_limit1 | |
forward_limit2 | |
forward_limit3 | |
aft_limit2 | |
aft_limit1 | |
echoLines = | |
uncurry Line <$> pairFive echoPoints | |
echoGradients = | |
fmap gradient echoLines | |
-- Q: An echo aeroplane is loaded and is on the forward limit. | |
-- The pilot decides to burn from the aux tanks first. | |
-- What will happen to the COG? | |
main :: | |
IO () | |
main = | |
let printPoint1 = | |
printf "%03.1f" | |
printPoint2 = | |
printf "%03d" | |
printGradient = | |
printf "%02.4f" | |
header x = | |
let v = "+------------------+-------+------+--------+" | |
in [v, x, v] | |
names = | |
Five "F limit (2000kg)" "F limit (2360kg)" "F limit (2950kg)" "A limit (2950kg)" "A limit (2000kg)" | |
row2 n p g = | |
[ | |
"| " <> n <> " | " <> printPoint1 (x p) <> " | " <> printPoint2 (y p) <> " | |" | |
, "| | | | " <> printGradient g <> " |" | |
] | |
in mapM_ putStrLn | |
( | |
header "| Point | IU | kg | Grad |" | |
<> | |
concat (toList (row2 <$> names <*> echoPoints <*> echoGradients)) | |
<> | |
header ("| Auxiliary Fuel Arm | " <> printGradient (aux_tank_arm / 10000) <> " |") | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment