Home

PureScript solution to Project Euler problem 49

2021-Oct-10 15:00
purescriptproject-euler

Problem details at Project Euler problem 49 page.

Test

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
module Euler049Test (euler49suite) where
 
import Prelude
 
import Data.BigInt (fromString)
import Data.Maybe (Maybe(..))
import Data.Traversable (sequence)
import Euler049 (euler49)
import Test.Unit (TestSuite, suite, test)
import Test.Unit.Assert as Assert
 
euler49suite :: TestSuite
euler49suite =
  suite "Euler 49" do
    test "Real" do
      Assert.equal (sequence [ fromString "148748178147"
                             , fromString "296962999629"
                             ])
                   (Just $ euler49 unit)

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
module Euler049 where
 
import Prelude
 
import Control.MonadZero (guard)
import Data.Array (filter, range, (:))
import Data.BigInt (BigInt, fromInt)
import Data.Set as S
 
isPrime :: Int -> Boolean
isPrime n =
  let go j
        | j * j > n      = true
        | n `mod` j == 0 = false
        | otherwise      = go (j + 1)
  in go 2
 
primes :: Int -> Array Int
primes n = filter isPrime $ range 2 n
 
digits :: Int -> Array Int
digits j
  | j < 10 = [j]
  | otherwise = j `mod` 10 : digits (j `div` 10)
 
cond :: Int -> Int -> Int -> Boolean
cond j k l =
  let dj = S.fromFoldable $ digits j
      dk = S.fromFoldable $ digits k
      dl = S.fromFoldable $ digits l
  in dj == dk && dk == dl
 
euler49 :: Unit -> Array BigInt
euler49 _ = do
  let ps = filter (_ >= 1000) (primes 10000)
      pss = S.fromFoldable ps
  j <- ps
  k <- ps
  let l = k + k - j
  guard $ j < k && k < l && l `S.member` pss && cond j k l
  pure $ (fromInt j * fromInt 10000 + fromInt k) * fromInt 10000 + fromInt l