icyrock.com

Home

PureScript solution to Project Euler problem 27

2019-Dec-03 23:37
purescriptproject-euler

Problem details at Project Euler problem 27 page.

Test

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
module Euler027Test (euler27suite) where
 
import Prelude
 
import Data.Maybe (Maybe(..))
import Euler027 (euler27)
import Test.Unit (TestSuite, suite, test)
import Test.Unit.Assert as Assert
 
euler27suite :: TestSuite
euler27suite =
  suite "Euler 27" do
    test "Warmup" do
      Assert.equal (Just (-41)) (euler27 1 41)
    test "Warmup 2" do
      Assert.equal (Just (-126479)) (euler27 79 1601)
    test "Real" do
      Assert.equal (Just (-59231)) (euler27 1000 1000)

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
44
45
46
47
48
module Euler027 where
 
import Prelude
 
import Data.Array (range)
import Data.Foldable (maximumBy)
import Data.Maybe (Maybe)
type Pcprod = { cprod :: Int, nmax :: Int }
 
prime :: Int -> Boolean
prime n
  | n < 1     = false
  | n <= 3    = true
  | otherwise =
      let go j k
            | j == k         = true
            | k `mod` j == 0 = false
            | otherwise      = go (j + 1) k
      in go 2 n
 
formula :: Int -> Int -> Int -> Int
formula a b n = n * n + a * n + b
 
pcmax :: Int -> Int -> Int
pcmax a b =
  let go j
        | prime $ formula a b j = go $ j + 1
        | otherwise = j - 1
  in go 0
 
pcprod :: Int -> Int -> Pcprod
pcprod a b = { cprod: a * b
             , nmax: pcmax a b
             }
 
pcprods :: Int -> Int -> Array Pcprod
pcprods am bm = do
  a <- range (-am) am
  b <- range (-bm) bm
  pure $ pcprod a b
 
pcprodCmp :: Pcprod -> Int
pcprodCmp { nmax } = nmax
 
euler27 :: Int -> Int -> Maybe Int
euler27 am bm = do
  { cprod } <- maximumBy (comparing pcprodCmp) (pcprods am bm)
  pure cprod