icyrock.com

Home

PureScript solution to Project Euler problem 26

2019-Nov-29 21:31
purescriptproject-euler

Problem details at Project Euler problem 26 page.

Test

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module Euler026Test (euler26suite) where
 
import Prelude
 
import Data.Maybe (Maybe(..))
import Euler026 (euler26)
import Test.Unit (TestSuite, suite, test)
import Test.Unit.Assert as Assert
 
euler26suite :: TestSuite
euler26suite =
  suite "Euler 26" do
    test "Warmup" do
      Assert.equal (Just 7) (euler26 10)
    test "Real" do
      Assert.equal (Just 983) (euler26 999)

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
module Euler026 where
 
import Prelude
 
import Data.Array (elemIndex, head, range, snoc, tail)
import Data.Foldable (maximumBy)
import Data.Maybe (Maybe(..), fromMaybe)
 
ufrac :: Int -> Array Int
ufrac n =
  let go _ k 0 = k
      go j k l = go (10 * (j - j / n * n)) (snoc k (j `mod` n)) (l - 1)
  in go 10 [] (2 * n)
 
ufracLen :: Int -> Int
ufracLen n =
  let j = ufrac n
      f = case elemIndex 0 j of
            Just _ -> 0
            Nothing -> g
      g = fromMaybe 0 do
        k <- head j
        l <- tail j
        elemIndex k l
  in f
 
rlen :: Int -> {num :: Int, len :: Int}
rlen n = { num: n
         , len: ufracLen n
         }
 
rlens :: Int -> Array {num :: Int, len :: Int}
rlens n = rlen <$> range 2 n
 
rlenMax :: Int -> Maybe {num :: Int, len :: Int}
rlenMax = rlens
  >>> (maximumBy $ comparing \{num, len} -> len)
 
euler26 :: Int -> Maybe Int
euler26 n = do
  {num, len} <- rlenMax n
  pure num