Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I have a function fib2 which returning two values as Tuple but I want to print the product of tuples returned by function fib2. I am new to Haskell so please explain it to me in a simple way.

This problem is from SPOJ which I have already solved using C and again I am trying it in Haskell:

For each \$n\$, find \$G(n) \mod 1000000007\$, where $$\begin{align*} G(0) &= 0 \\ G(n) &= G(n-1) + f(4n - 1), \qquad n > 0 \\ f(i) &= \mathrm{the\ i^{th}\ Fibobacci\ number} \end{align*}$$

The first line of input specifies the number of test cases.

Now my code is working fine but I'm getting TLE in this problem. Can someone show me how to optimize Fibonacci in Haskell?

import Data.List
import Data.Maybe
import Control.Monad
import qualified Data.ByteString.Char8 as C


fib2 0 = (1, 1)
fib2 1 = (1, 2)
fib2 n
 | even n    = ((a*a + b*b)`mod` 1000000007, (c*c - a*a)`mod` 1000000007)
 | otherwise = ((c*c - a*a)`mod` 1000000007, (b*b + c*c)`mod` 1000000007)
 where (a,b) = fib2 (n `div` 2 - 1)
       c     = a + b

solve n = (a*b)`mod`1000000007
    where (a,b) = fib2((2*n-1)`mod`2000000016)

main = C.getContents >>= putStrLn . unlines . map (show.solve.fromIntegral . fst . fromJust . C.readInteger) . tail . C.words
share|improve this question
1  
Basically, your code looks good. I get a ~25% speedup by making it a little stricter, !c = a + b in the where clause of fib2 (requires {-# LANGUAGE BangPatterns #-} at the top), and a small improvement from using quot and rem instead of div and mod. I'm not sure of the compile options SPOJ passes, so adding {-# OPTIONS_GHC -O2 #-} after the language pragma might be required. –  Daniel Fischer Jan 9 at 21:10
    
@DanielFischer Thanks for your answer. Yes I am getting compile error after changing c = a+b to !c = a + b getting Illegal bang-pattern (use -XBangPatterns). I will try to rectify this. –  Lakshman Jan 10 at 8:55
    
EDIT1:: Yes using quot and rem I got 30% speed up. But Still TLE. –  Lakshman Jan 10 at 9:06
    
You must put the language pragma at the top of the source file to use bang patterns. And have you also the optimisation pragma in the file? If SPOJ doesn't pass -O2 as a compilation flag, you absolutely need it. –  Daniel Fischer Jan 10 at 10:12
    
I tested my algorithm with quot and rem for another Fibonacci like problem on SPOJ. My initial AC was taking .58s after using rem and quot it reduced to .39s. –  Lakshman Jan 10 at 10:16

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.