icyrock.com

Home

PureScript solution to Project Euler problem 32

2020-May-12 19:27
purescriptproject-euler

Problem details at Project Euler problem 32 page.

Test

1
2
3
4
5
6
7
8
9
10
11
12
13
module Euler032Test (euler32suite) where
 
import Prelude
 
import Euler032 (euler32)
import Test.Unit (TestSuite, suite, test)
import Test.Unit.Assert as Assert
 
euler32suite :: TestSuite
euler32suite =
  suite "Euler 32" do
    test "Real" do
      Assert.equal 45228 (euler32 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
42
43
module Euler032 where
 
import Prelude
 
import Data.Array as A
import Data.Foldable (sum)
import Data.Set (Set)
import Data.Set as S
 
dall :: Array Int
dall = A.range 1 9
 
digits :: Int -> Array Int
digits j
  | j < 1     = []
  | otherwise = digits (j / 10) `A.snoc` (j `mod` 10)
 
pandigital :: Int -> Int -> Int -> Boolean
pandigital j k l =
  let dj = digits j
      dk = digits k
      dl = digits l
  in
    (A.length dj + A.length dk + A.length dl) == 9
    && A.sort (A.concat [dj, dk, dl]) == dall
 
pdone :: Int -> Int -> Int -> Int -> Int -> Set Int -> Set Int
pdone j jg kf kg k s
  | j > jg    = s
  | k > kg    = pdone (j + 1) jg kf kg kf s
  | otherwise =
      let f = j * k
          g = pandigital j k f
          d = if g then S.insert f s else s
      in pdone j jg kf kg (k + 1) d
 
pandigitals :: Unit -> Set Int
pandigitals _ =
  S.union (pdone 1 9 1234 9876 1234 S.empty)
          (pdone 12 98 123 987 123 S.empty)
 
euler32 :: Unit -> Int
euler32 _ = sum $ pandigitals unit