Bryce
Bryce

Reputation: 320

Project Euler 12 with Haskell's State Monad

In trying to increase my Haskell knowledge I thought I'd try and get the 12th Project Euler problem solved using the State Monad. It seemed to make sense to me at the time to incorporate the whole triangle number creation with putting it in state.

Here is my code:

module Main where

import Control.Monad
import Control.Monad.State

type MyState = (Integer, Integer)
s0 = (7, 28)

tick :: State MyState Int
tick = do 
    (n,o) <- get
    let divs = getDivLen (n,o)
    if divs >= 500
        then do
            let n' = n + 1
            let o' = o + n'
            put (n', o')
            tick
        else
            return divs

getDivLen :: MyState -> Int
getDivLen (n,o) = foldl1 (+) [2 | x <- [1..x], o `mod` x == 0]
    where x = round . sqrt $ fromIntegral o

main :: IO ()
main = print $ evalState tick s0

The code compiles and I get the result 6 to the console. I'm just not sure what I'm doing wrong to not have the recursion happen.

Thanks in advance.

Upvotes: 1

Views: 299

Answers (1)

hammar
hammar

Reputation: 139900

Looks like you have your loop condition backwards. You're only recursing if you've found a triangle number with at least 500 divisors, so it will of course stop immediately since the first one has fewer than that.

To fix this, change the line if divs >= 500 to if divs < 500.

Once you've done that, you're supposed to return the number itself, not the number of divisors, so you'll have to fix the return divs as well. I'll leave fixing that part to you.

Upvotes: 1

Related Questions