Skip to content

Instantly share code, notes, and snippets.

@rby
Created April 21, 2011 13:18
Show Gist options
  • Save rby/934446 to your computer and use it in GitHub Desktop.
Save rby/934446 to your computer and use it in GitHub Desktop.
fib implementation in supposed log(n)
{-# LANGUAGE BangPatterns #-}
module Main where
import Test.QuickCheck
import System (getArgs)
data M = M !Integer !Integer !Integer !Integer
M a b c d <*> M a' b' c' d' =
M (a*a'+b*c') (a*b'+b*d')
(c*a'+d*c') (c*b'+d*d')
mpow :: M -> Int -> M
m `mpow` 0 = m
m `mpow` (n + 1)| odd n = m' <*> m'
| otherwise = (m `mpow` n) <*> M 1 1 1 0
where m' = m `mpow` div n 2
fib :: Int -> Integer
fib n = let M x _ _ _ = identity `mpow` n in x
where identity = M 1 0 0 1
fibs :: [Integer]
fibs = 1:1:zipWith (+) fibs (tail fibs)
test :: IO ()
test = let theorem n = fibs !! n == fib n
in quickCheck $ forAll (choose (1,200)) theorem
main :: IO ()
main = getArgs >>= print . fib . read . head
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment