This one is based on my original code with improvements suggested by leventov leventov. Down to 0.7 seconds from the initial 6 seconds thanks to tail recursion and bitwise operations.
import Data.Bits
collatzLength :: Int -> Int -> Int
collatzLength sum x
| x == 1 = sum
| testBit x 0 = collatzLength (sum + 2) (shiftR (3*x + 1) 1)
| otherwise = collatzLength (sum + 1) (shiftR x 1)
main = print $ foldl collatzLength 0 [1..3000000]
This one is based on my original code with improvements suggested by leventov. Down to 0.7 seconds from the initial 6 seconds thanks to tail recursion and bitwise operations.
import Data.Bits
collatzLength :: Int -> Int -> Int
collatzLength sum x
| x == 1 = sum
| testBit x 0 = collatzLength (sum + 2) (shiftR (3*x + 1) 1)
| otherwise = collatzLength (sum + 1) (shiftR x 1)
main = print $ foldl collatzLength 0 [1..3000000]
This one is based on my original code with improvements suggested by leventov. Down to 0.7 seconds from the initial 6 seconds thanks to tail recursion and bitwise operations.
import Data.Bits
collatzLength :: Int -> Int -> Int
collatzLength sum x
| x == 1 = sum
| testBit x 0 = collatzLength (sum + 2) (shiftR (3*x + 1) 1)
| otherwise = collatzLength (sum + 1) (shiftR x 1)
main = print $ foldl collatzLength 0 [1..3000000]
- 683
- 4
- 12
This version is almost identical to leventov 's, but I've added more descriptive variable names, slightly simplified the top level function, and fixed an off-by-one error:
import Data.Bits
sumCollatz :: Int -> Int -> Int
sumCollatz 1 sum = sum
sumCollatz x sum = sumCollatz (x - 1) (f x sum)
where f = if testBit x 0 then addOdd else addEven
addEven x sum = f (shiftR x 1) (sum + 1)
where f = if testBit x 1 then addOdd else addEven
addOdd 1 sum = sum
addOdd x sum = addEven (3 * x + 1) (sum + 1)
main = print $ sumCollatz 3000000 0
And this one is based on my original code with some improvements suggested by leventov leventov. While a tad slower thanDown to 0.7 seconds from the previous one, it's more readable:initial 6 seconds thanks to tail recursion and bitwise operations.
import Data.Bits
collatzLength :: Int -> Int -> Int
collatzLength sum x
| x == 1 = sum
| testBit x 0 = collatzLength (sum + 2) (shiftR (3*x + 1) 1)
| otherwise = collatzLength (sum + 1) (shiftR x 1)
main = print $ foldl collatzLength 0 [1..3000000]
The speed gain compared to the original comes from tail recursion and bitwise operations.
This version is almost identical to leventov 's, but I've added more descriptive variable names, slightly simplified the top level function, and fixed an off-by-one error:
import Data.Bits
sumCollatz :: Int -> Int -> Int
sumCollatz 1 sum = sum
sumCollatz x sum = sumCollatz (x - 1) (f x sum)
where f = if testBit x 0 then addOdd else addEven
addEven x sum = f (shiftR x 1) (sum + 1)
where f = if testBit x 1 then addOdd else addEven
addOdd 1 sum = sum
addOdd x sum = addEven (3 * x + 1) (sum + 1)
main = print $ sumCollatz 3000000 0
And this one is based on my original code with some improvements suggested by leventov. While a tad slower than the previous one, it's more readable:
import Data.Bits
collatzLength :: Int -> Int -> Int
collatzLength sum x
| x == 1 = sum
| testBit x 0 = collatzLength (sum + 2) (shiftR (3*x + 1) 1)
| otherwise = collatzLength (sum + 1) (shiftR x 1)
main = print $ foldl collatzLength 0 [1..3000000]
The speed gain compared to the original comes from tail recursion and bitwise operations.
This one is based on my original code with improvements suggested by leventov. Down to 0.7 seconds from the initial 6 seconds thanks to tail recursion and bitwise operations.
import Data.Bits
collatzLength :: Int -> Int -> Int
collatzLength sum x
| x == 1 = sum
| testBit x 0 = collatzLength (sum + 2) (shiftR (3*x + 1) 1)
| otherwise = collatzLength (sum + 1) (shiftR x 1)
main = print $ foldl collatzLength 0 [1..3000000]
- 683
- 4
- 12
This version is almost identical to leventov's, but I've added more descriptive variable names, slightly simplified the top level function, and fixed an off-by-one error:
import Data.Bits
sumCollatz :: Int -> Int -> Int
sumCollatz 1 sum = sum
sumCollatz x sum = sumCollatz (x - 1) (f x sum)
where f = if testBit x 0 then addOdd else addEven
addEven x sum = f (shiftR x 1) (sum + 1)
where f = if testBit x 1 then addOdd else addEven
addOdd 1 sum = sum
addOdd x sum = addEven (3 * x + 1) (sum + 1)
main = print $ sumCollatz 3000000 0
And this one is based on my original code with some improvements suggested by leventov. While a tad slower than the previous one, it's still quite fast andmore readable:
import Data.Bits
collatzLength :: Int -> Int -> Int
collatzLength sum x
| x == 1 = sum
| testBit x 0 = collatzLength (sum + 12) (3 *shiftR x(3*x + 1) 1)
| otherwise = collatzLength (sum + 1) (shiftR x 1)
main = print $ sum $ mapfoldl (collatzLength 0) [1..3000000]
The speed gain compared to the original comes from tail recursion and bitwise operations.
This version is almost identical to leventov's, but I've added more descriptive variable names, slightly simplified the top level function, and fixed an off-by-one error:
import Data.Bits
sumCollatz :: Int -> Int -> Int
sumCollatz 1 sum = sum
sumCollatz x sum = sumCollatz (x - 1) (f x sum)
where f = if testBit x 0 then addOdd else addEven
addEven x sum = f (shiftR x 1) (sum + 1)
where f = if testBit x 1 then addOdd else addEven
addOdd 1 sum = sum
addOdd x sum = addEven (3 * x + 1) (sum + 1)
main = print $ sumCollatz 3000000 0
And this one is based on my original code with some improvements suggested by leventov. While slower than the previous one, it's still quite fast and readable:
import Data.Bits
collatzLength :: Int -> Int -> Int
collatzLength sum x
| x == 1 = sum
| testBit x 0 = collatzLength (sum + 1) (3 * x + 1)
| otherwise = collatzLength (sum + 1) (shiftR x 1)
main = print $ sum $ map (collatzLength 0) [1..3000000]
The speed gain compared to the original comes from tail recursion and bitwise operations.
This version is almost identical to leventov's, but I've added more descriptive variable names, slightly simplified the top level function, and fixed an off-by-one error:
import Data.Bits
sumCollatz :: Int -> Int -> Int
sumCollatz 1 sum = sum
sumCollatz x sum = sumCollatz (x - 1) (f x sum)
where f = if testBit x 0 then addOdd else addEven
addEven x sum = f (shiftR x 1) (sum + 1)
where f = if testBit x 1 then addOdd else addEven
addOdd 1 sum = sum
addOdd x sum = addEven (3 * x + 1) (sum + 1)
main = print $ sumCollatz 3000000 0
And this one is based on my original code with some improvements suggested by leventov. While a tad slower than the previous one, it's more readable:
import Data.Bits
collatzLength :: Int -> Int -> Int
collatzLength sum x
| x == 1 = sum
| testBit x 0 = collatzLength (sum + 2) (shiftR (3*x + 1) 1)
| otherwise = collatzLength (sum + 1) (shiftR x 1)
main = print $ foldl collatzLength 0 [1..3000000]
The speed gain compared to the original comes from tail recursion and bitwise operations.
- 683
- 4
- 12