Skip to content

Instantly share code, notes, and snippets.

@MichaelBurge
Created March 21, 2018 04:16
Show Gist options
  • Save MichaelBurge/f142e930f97a8898a7b862f7f5a67852 to your computer and use it in GitHub Desktop.
Save MichaelBurge/f142e930f97a8898a7b862f7f5a67852 to your computer and use it in GitHub Desktop.
First Haskell I ever wrote
import System( getArgs )
import System.Console.GetOpt
import System.IO
import Ratio
import Numeric
{- Returns the binomial coefficient. -}
binomial m 0 = 1
binomial 0 n = 0
binomial (m+1) (n+1) = (binomial m n) * (m+1) `div` (n+1)
{- Returns n! -}
fact 0 = 1
fact k = k * (fact $ k-1)
{- Scans through the list applying the binary function to each set of
2 elements. -}
foldl2 :: (Integer->Integer->Integer)->[Integer] -> [Integer]
foldl2 f [] = []
foldl2 f [x] = []
foldl2 f (x:y:[]) = [f y x]
foldl2 f (x:y:xs) = (f y x):(foldl2 f (y:xs))
{- Returns the binomial transform of the given list -}
binomialTransform :: [Integer] -> [Integer]
binomialTransform [] = []
binomialTransform list@(x:xs) = x : (binomialTransform $ foldl2 (-) list)
{- Returns the Inverse Binomial Transform of the given list. -}
inverseBinomialTransform :: [Integer] -> [Integer]
inverseBinomialTransform [] = []
inverseBinomialTransform list@(x:xs) = x : (inverseBinomialTransform $ foldl2 (+) list)
{- Removes the trailing zeros at the end of a list -}
removeEndZeros :: [Integer] -> [Integer]
removeEndZeros xs = reverse $ dropWhile (0==) $ reverse xs
{- Forms a sequence of nth powers- 0^n,1^n,2^n,3^n,etc. -}
nthDegreePoly :: [Integer ] -> [Integer]
nthDegreePoly n = [x^n | x<-[0..]]
{- Forms an nth power sequence with each element having a matching coefficient in xs. -}
{- Returns the coefficients of a polynomial(centered at 0) that fits the given list. -}
fitPolynomial :: [Integer] -> [Integer]
fitPolynomial [] = []
fitPolynomial xs = fitPolynomial $
zipWith (-) xs (
zipWith (*) i (
nthDegreePoly $ length i))
where i = removeEndZeros $ binomialTransform
{- Returns the average of the given list -}
average :: [Integer] -> Rational
average [] = 0
average x = (sum x) % (fromIntegral $ length x)
{- Returns the geometric mean of a given list -}
geometricMean :: [Integer] -> Double
geometricMean [] = 1
geometricMean x = exp $ sum $ map (\y->((log $ fromInteger y)/(fromIntegral $ length x))) x
{- Returns a sequence of geometric means for the given list -}
subsequenceTransform :: ([a]->b)->[a] -> [b]
subsequenceTransform f [] = []
subsequenceTransform f x = (subsequenceTransform f $ init x) ++ [f x]
listToInt :: [String] -> [Integer]
listToInt x = map read x
main = do
args <- getArgs
putStrLn $ "List: " ++ (show $ listToInt args)
putStrLn $ "Difference: " ++ (show $ foldl2 (-) $ listToInt args)
putStrLn $ "Sum: " ++ (show $ foldl2 (+) $ listToInt args)
putStrLn $ "Binomial: " ++ (show $ binomialTransform $ listToInt args)
putStrLn $ "Inverse Binomial: " ++ (show $ inverseBinomialTransform $ listToInt args)
putStrLn $ "Average: " ++ (show $ subsequenceTransform average $ listToInt args)
putStrLn $ "Geometric Means: " ++ (show $ subsequenceTransform geometricMean $ listToInt args)
putStrLn $ show $ fitPolynomial $ listToInt args
putStrLn $ show $ removeEndZeros$ listToInt args
{-
1 4 9 16 25 36 49 64 81 100 120
3 5 7 9 11 13 15 17 19 20
2 2 2 2 2 2 2 2 2 1
0 0 0 0 0 0 0 0 -1
0 0 0 0 0 0 0 -1
0 0 0 0 0 0 -1
-}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment