
import System.CPUTime import Text.Printf (printf) import Data.List (findIndex) time :: (Show a) => a -> IO a time result = do start <- getCPUTime let computed = result end <- computed `seq` getCPUTime let diff = (fromIntegral (end - start)::Float)/(10^12) printf "Result: %s\n Time taken: %.6f seconds\n" (show computed) diff return computed matrixMultiply :: Num a => [(a, a)] -> [(a, a)] -> [(a, a)] matrixMultiply [(a11, a12), (a21, a22)] [(b11, b12), (b21, b22)] = [ (a11*b11 + a12*b21, a11*b12 + a12*b22) , (a21*b11 + a22*b21, a21*b12 + a22*b22) ] matrixPower :: Num a => [(a, a)] -> Int -> [(a, a)] matrixPower m 1 = m matrixPower m n = let half = matrixPower m (n `div` 2) squared = matrixMultiply half half in if odd n then matrixMultiply squared m else squared digitsInNumber :: (Show a, Integral a) => a -> Int digitsInNumber = length . show fibNth :: Integral a => a -> a fibNth n | n <= 2 = 1 | otherwise = fst $ head $ matrixPower [(1, 1), (1, 0)] (fromIntegral (n - 1)) fibUpperBound :: Int -> Integer fibUpperBound digitCount = let phi = 1.618033988749895 logPhi = logBase 10 phi log5 = logBase 10 5 in ceiling $ (fromIntegral digitCount - 1 + (log5 / 2)) / logPhi binarySearchFibIndex :: Int -> Maybe Integer binarySearchFibIndex digitCount = let upperBound = fibUpperBound digitCount binarySearch left right | left > right = Nothing | otherwise = let mid = left + (right - left) `div` 2 midFib = fibNth mid midDigits = digitsInNumber midFib in case compare midDigits digitCount of EQ -> let prevDigits = digitsInNumber $ fibNth (mid - 1) in if prevDigits < digitCount then Just mid else binarySearch left (mid - 1) LT -> binarySearch (mid + 1) right GT -> binarySearch left (mid - 1) in binarySearch 1 upperBound
λ> time $ binarySearchFibIndex 1000 Result: Just 4782 Time taken: 0.000852 seconds Just 4782 λ>
λ> time $ binarySearchFibIndex 1000 Result: Just 4782 Time taken: 0.006747 seconds Just 4782 λ>
— Me@2024-12-25 07:00:13 AM
.
.
2025.01.01 Wednesday (c) All rights reserved by ACHK

You must be logged in to post a comment.