2023-03-11 09:28
Problem details at Project Euler problem 65 page.
module Euler065Test (euler65suite) where
import Prelude
import Effect.Aff (Milliseconds(..), delay)
import Euler065 (euler65)
import Test.Unit (TestSuite, suite, test)
import Test.Unit.Assert as Assert
euler65suite :: TestSuite
euler65suite =
suite "Euler 65" do
test "Warmup" do
delay (Milliseconds 0.0)
Assert.equal 17 (euler65 10)
test "Real" do
delay (Milliseconds 0.0)
Assert.equal 272 (euler65 100)
module Euler065 where
import Prelude
import Data.Array.NonEmpty (concatMap, foldl1, range, reverse, take)
import Data.Array.NonEmpty.Internal (NonEmptyArray(..))
import Data.BigInt (BigInt, digitsInBase, fromInt)
import Data.Foldable (sum)
import Data.Ratio (Ratio, numerator, (%))
terms :: Int -> NonEmptyArray BigInt
terms n =
let f j = NonEmptyArray (map fromInt [1, 1, j * 2])
r = concatMap f $ range 2 (4 + n / 3)
in NonEmptyArray $ take n (NonEmptyArray (map fromInt [2, 1, 2]) <> r)
convergent :: Int -> Ratio BigInt
convergent n =
let rts = (_ % fromInt 1) <$> reverse (terms n)
r1 = fromInt 1 % fromInt 1
f a e = e + r1 / a
in foldl1 f rts
euler65 :: Int -> Int
euler65 = sum <<< _.value <<< digitsInBase 10 <<< numerator <<< convergent