Project Euler 12 与 Haskell 的 State Monad

发布于 2025-01-03 20:34:32 字数 777 浏览 0 评论 0原文

在尝试增加我的 Haskell 知识时,我想尝试使用 State Monad 解决第 12 个 Project Euler 问题。当时对我来说,将整个三角形数字的创建与将其置于状态中似乎是有意义的。

这是我的代码:

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

代码编译后,我将结果 6 发送到控制台。我只是不确定我做错了什么而没有发生递归。

提前致谢。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

少女情怀诗 2025-01-10 20:34:32

看起来你的循环条件倒退了。只有当你找到一个至少有 500 个约数的三角形数时,你才会进行递归,所以它当然会立即停止,因为第一个三角形的约数少于这个数。

要解决此问题,请将行 if divs >= 500 更改为 if divs <; 500

完成此操作后,您应该返回数字本身,而不是除数的数量,因此您还必须修复返回 div。我会把那部分的问题留给你来解决。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文