Skip to main content
deleted 35 characters in body
Source Link
max taldykin
  • 1.4k
  • 9
  • 13

Haskell is great for it's declarative style programs and most of the first hundred Project Euler problems are easy to write in such a way.

First of all, this problem is about ratios, so let us import Data.Ratio module.

import Data.Ratio (Ratio, numerator, denominator)

From that nice formula it is easy to see that the process of computing √2 is iterative. You just need to decide what function to iterate. Let us consider this one:

f :: Ratio Integer -> Ration Integer
f x = 1 + 1 / (1 + x)

You can check in GHCi that it is somehow relevant to the problem:

*Main> f 1
3 % 2
*Main> f it
7 % 5
*Main> f it
17 % 12
*Main> f it
41 % 29

(it is the result of the last computation in GHCi.)

There is a function iterate :: (a -> a) -> a -> [a] in Prelude that captures such a process of applying some function to the result of applying that function to the .... and so ad infinitum.

rootExpansions :: [Ratio Integer]
rootExpansions = iterate f 1

Now, when you have all of the expansions, you need to filter and count those with numerator longer than denominator.

numIsLonger :: Ratio Integer -> Bool
numIsLonger x = length (show $ numerator x) > length (show $ denominator x)

Having all parts ready you can write solution in a declarative style

main :: IO ()
main
  = print
  $ length
  $ filter numIsLonger
  $ take 1000
  $ rootExpansion

As an extra bonus, here is unreadable minified solution:

import GHC.Real (Ratio(..))
import Data.Ord (comparing)

main :: IO ()
main
  = print
  $ length
  $ filter (\(n :% d) -> comparing (length . (show) n) d> ==length GT(show d))
  $ take 1000
  $ iterate (\x -> 1 + 1 / (1 + x)) 1

Haskell is great for it's declarative style programs and most of the first hundred Project Euler problems are easy to write in such a way.

First of all, this problem is about ratios, so let us import Data.Ratio module.

import Data.Ratio (Ratio, numerator, denominator)

From that nice formula it is easy to see that the process of computing √2 is iterative. You just need to decide what function to iterate. Let us consider this one:

f :: Ratio Integer -> Ration Integer
f x = 1 + 1 / (1 + x)

You can check in GHCi that it is somehow relevant to the problem:

*Main> f 1
3 % 2
*Main> f it
7 % 5
*Main> f it
17 % 12
*Main> f it
41 % 29

(it is the result of the last computation in GHCi.)

There is a function iterate :: (a -> a) -> a -> [a] in Prelude that captures such a process of applying some function to the result of applying that function to the .... and so ad infinitum.

rootExpansions :: [Ratio Integer]
rootExpansions = iterate f 1

Now, when you have all of the expansions, you need to filter and count those with numerator longer than denominator.

numIsLonger :: Ratio Integer -> Bool
numIsLonger x = length (show $ numerator x) > length (show $ denominator x)

Having all parts ready you can write solution in a declarative style

main :: IO ()
main
  = print
  $ length
  $ filter numIsLonger
  $ take 1000
  $ rootExpansion

As an extra bonus, here is unreadable minified solution:

import GHC.Real (Ratio(..))
import Data.Ord (comparing)

main :: IO ()
main
  = print
  $ length
  $ filter (\(n :% d) -> comparing (length . show) n d == GT)
  $ take 1000
  $ iterate (\x -> 1 + 1 / (1 + x)) 1

Haskell is great for it's declarative style programs and most of the first hundred Project Euler problems are easy to write in such a way.

First of all, this problem is about ratios, so let us import Data.Ratio module.

import Data.Ratio (Ratio, numerator, denominator)

From that nice formula it is easy to see that the process of computing √2 is iterative. You just need to decide what function to iterate. Let us consider this one:

f :: Ratio Integer -> Ration Integer
f x = 1 + 1 / (1 + x)

You can check in GHCi that it is somehow relevant to the problem:

*Main> f 1
3 % 2
*Main> f it
7 % 5
*Main> f it
17 % 12
*Main> f it
41 % 29

(it is the result of the last computation in GHCi.)

There is a function iterate :: (a -> a) -> a -> [a] in Prelude that captures such a process of applying some function to the result of applying that function to the .... and so ad infinitum.

rootExpansions :: [Ratio Integer]
rootExpansions = iterate f 1

Now, when you have all of the expansions, you need to filter and count those with numerator longer than denominator.

numIsLonger :: Ratio Integer -> Bool
numIsLonger x = length (show $ numerator x) > length (show $ denominator x)

Having all parts ready you can write solution in a declarative style

main :: IO ()
main
  = print
  $ length
  $ filter numIsLonger
  $ take 1000
  $ rootExpansion

As an extra bonus, here is unreadable minified solution:

import GHC.Real (Ratio(..))

main :: IO ()
main
  = print
  $ length
  $ filter (\(n :% d) -> length (show n) > length (show d))
  $ take 1000
  $ iterate (\x -> 1 + 1 / (1 + x)) 1
Source Link
max taldykin
  • 1.4k
  • 9
  • 13

Haskell is great for it's declarative style programs and most of the first hundred Project Euler problems are easy to write in such a way.

First of all, this problem is about ratios, so let us import Data.Ratio module.

import Data.Ratio (Ratio, numerator, denominator)

From that nice formula it is easy to see that the process of computing √2 is iterative. You just need to decide what function to iterate. Let us consider this one:

f :: Ratio Integer -> Ration Integer
f x = 1 + 1 / (1 + x)

You can check in GHCi that it is somehow relevant to the problem:

*Main> f 1
3 % 2
*Main> f it
7 % 5
*Main> f it
17 % 12
*Main> f it
41 % 29

(it is the result of the last computation in GHCi.)

There is a function iterate :: (a -> a) -> a -> [a] in Prelude that captures such a process of applying some function to the result of applying that function to the .... and so ad infinitum.

rootExpansions :: [Ratio Integer]
rootExpansions = iterate f 1

Now, when you have all of the expansions, you need to filter and count those with numerator longer than denominator.

numIsLonger :: Ratio Integer -> Bool
numIsLonger x = length (show $ numerator x) > length (show $ denominator x)

Having all parts ready you can write solution in a declarative style

main :: IO ()
main
  = print
  $ length
  $ filter numIsLonger
  $ take 1000
  $ rootExpansion

As an extra bonus, here is unreadable minified solution:

import GHC.Real (Ratio(..))
import Data.Ord (comparing)

main :: IO ()
main
  = print
  $ length
  $ filter (\(n :% d) -> comparing (length . show) n d == GT)
  $ take 1000
  $ iterate (\x -> 1 + 1 / (1 + x)) 1