# icyrock.com

HomeOld blogOld blog 2

# PureScript solution to Project Euler problem 59

`2022-09-26 17:37`

Problem details at Project Euler problem 59 page.

## Test

``````module Euler059Test (euler59suite) where

import Prelude

import Effect.Class (liftEffect)
import Effect.Aff (Milliseconds(..), delay)
import Euler059 (euler59)
import Test.Unit (TestSuite, suite, test)
import Test.Unit.Assert as Assert

euler59suite :: TestSuite
euler59suite =
suite "Euler 59" do
test "Real" do
delay (Milliseconds 0.0)
Assert.equal 129448 =<< liftEffect euler59

``````

## Solution

``````module Euler059 where

import Prelude

import Data.Array (concat, drop, filter, head, length, range, snoc, take, zipWith)
import Data.Char (toCharCode)
import Data.Foldable (sum)
import Data.Int (fromString)
import Data.Int.Bits (xor)
import Data.Maybe (fromJust)
import Data.String (Pattern(..), split)
import Data.String.CodeUnits (toCharArray)
import Effect (Effect)
import Node.Encoding (Encoding(..))
import Partial.Unsafe (unsafePartial)

toCodes :: String -> Array Int
toCodes txt =
let as = split (Pattern ",") txt
in map (unsafePartial fromJust <<< fromString) as

passwords :: Int -> Array (Array Int)
let go :: Int -> Array (Array Int) -> Array (Array Int)
go 0 as = as
go n as =
go (n - 1) do
bs <- as
cs <- range 97 122
pure \$ bs `snoc` cs
in go l [[]]

doXor :: Array Int -> Array Int -> Array Int
doXor cs ps =
let r = (length cs `div` length ps) + 1
rep 0 _  = []
rep n as = concat [as, rep (n - 1) as]
in zipWith xor cs (rep r ps)

xors :: String -> Array (Array Int)
xors txt =
let cs = toCodes txt
in map (doXor cs) ps

isEnglish :: Array Int -> Boolean
isEnglish as =
let wc = map toCharCode <<< toCharArray
find _ [] = false
find ns bs
| take (length ns) bs == ns = true
| otherwise                 = find ns (drop 1 bs)
in find (wc "have") as && find (wc "the") as

findEnglish :: String -> Array Int
findEnglish = unsafePartial fromJust <<< head <<< filter isEnglish <<< xors

solve :: String -> Int
solve = sum <<< findEnglish

euler59 :: Effect Int
euler59 = do