Home

PureScript solution to Project Euler problem 42

2021-Mar-19 21:10
purescriptproject-euler

Problem details at Project Euler problem 42 page.

Test

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
module Euler042Test (euler42suite) where
 
import Prelude
 
import Data.Either (Either(..))
import Effect.Class (liftEffect)
import Euler042 (euler42)
import Node.Encoding (Encoding(..))
import Node.FS.Sync (readTextFile)
import Test.Unit (TestSuite, suite, test)
import Test.Unit.Assert as Assert
 
euler42suite :: TestSuite
euler42suite =
  suite "Euler 42" do
    test "Warmup" do
      Assert.equal (Right 3) (euler42 "\"A\",\"B\",\"C\",\"SKY\"")
    test "Real" do
      t <- liftEffect $ readTextFile UTF8 "etc/042-words-real.txt"
      Assert.equal (Right 162) (euler42 t)

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
module Euler042 where
 
import Prelude
 
import Data.Array (filter, fromFoldable, length, range, some)
import Data.Char (toCharCode)
import Data.Either (Either)
import Data.Foldable (sum)
import Data.Set as S
import Data.String.CodeUnits (fromCharArray, toCharArray)
import Text.Parsing.Parser (ParseError, Parser, runParser)
import Text.Parsing.Parser.Combinators as PC
import Text.Parsing.Parser.String (string)
import Text.Parsing.Parser.Token (letter)
 
wordsp :: Parser String (Array String)
wordsp =
  let qwp = PC.between (string "\"") (string "\"")
                       (fromCharArray <$> some letter)
  in fromFoldable <$> PC.sepBy qwp (string ",")
 
wordVal :: String -> Int
wordVal =
  let f j = toCharCode j - toCharCode 'A' + 1
  in sum <<< map f <<< toCharArray
 
euler42 :: String -> Either ParseError Int
euler42 t = do
  let wse = runParser t wordsp
      ts = S.fromFoldable $ map (\j -> j * (j + 1) / 2) (range 1 100)
      f = length <<< filter (flip S.member ts) <<< map wordVal
  map f wse