[Haskell-beginners] Monadic Project Euler 1
Ozgur Akgun
ozgurakgun at gmail.com
Thu Feb 17 20:54:53 CET 2011
On 17 February 2011 19:13, Javier M Mora <jamarier at gmail.com> wrote:
> First Step: What I want?
> ------------------------
>
> In this problem: I think monads as a DSL (Domain Specific Language)
>
> main = do
> print $ sumM $ do
> makeList 10 -- create candidates list
> multiples 3 -- choose multiples of 3
> multiples 5 -- choose multiples of 5 (not choosed yet)
>
> Data under de monad is a pair of lists:
> (validValues, CandidatesNonValidYet)
>
Although my suggestion is not to use a monad for this problem, assuming this
is a learning exercise, a solution using the state monad is as follows.
I'll keep the main function exactly as you wanted.
sumM x = sum $ fst $ execState ([],[]) x
or, point-free:
sumM = sum . fst . flip execState ([],[])
Here, sumM executes the given state monad, and we end up with the pair of
selected and not-selected elements. Then project the fst component, and sum
them up.
makeList n = put ([],[1..n])
makeList initialises the state.
multiples n = chooseIf (\ i -> i `mod` n == 0)
multiplies chooses those elements satisfying the given criteria. chooseIf is
a helper function I've chosen to define. Obviously, you can do just fine
without it.
chooseIf f = do
a <- gets fst
(b,c) <- partition f <$> gets snd
put (a++b,c)
chooseIf partitions the list of candidates into 2, b is the list of elements
satisfying the condition, c is the elements not satisfying it. (Remark: ++
is O(n))
And that should be it. If you plug these all together, you'll get 33 as the
answer. That is the sum of [3,6,9,5,10]. I don't know why you didn't include
10 in the list of candidates, but if that is very important you can remove
it by modifying makeList.
Hope this helps.
Ozgur
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20110217/03032d03/attachment.htm>
More information about the Beginners
mailing list