【问题标题】:Questions regarding Haskell solution of Project Euler 14关于 Project Euler 14 的 Haskell 解决方案的问题
【发布时间】:2015-09-13 15:25:18
【问题描述】:

这是Question 14

import Data.Array
import Data.List
import Data.Ord (comparing)

syrs n = a
  where 

    -- For those who don't want to lookup array in the reference
    -- the following line creates an array indexed from 1 to n 
    -- using the list provided. And a ! x is the syntax for a[x] in some other languages.

    a = listArray (1,n) $ 0 : [1 + syr n x | x <- [2..n]]   -------- 2
    syr n x = if x' <= n                                    -------- 1
            then a ! x'                                     -------- 1
            else 1 + syr n x'                               
      where 
        x' = if even x
             then x `div` 2
             else 3 * x + 1

main = print $ maximumBy (comparing snd) $ assocs $ syrs 1000000

以上是Project Euler Q14 on wiki.haskell.org 的建议解决方案。该算法与我的算法基本相同(但我的算法永远运行,而它在 2 秒内运行)。

问题:

在第 2 行,它调用syr n x。假设x = 3x' = 1010 &lt; n,它将继续then子句:a ! 10。但此时,a ! 10 尚未计算。那么程序如何进行呢?


【问题讨论】:

  • 你想整理一下这种格式吗?我认为没有多少人可以阅读它...
  • @AJFarmar 我应该如何整理格式?代码前的问题?
  • 如果它是有效的haskell 代码,那就太好了,但我想我现在可以为你做。我先编辑一下。
  • 我猜他说的是缩进。但我也会简化代码并删除“a”:我会说syrs n = listArray (1,n) ...
  • 请完整发布您自己的损坏代码。阅读代码时很难进行心理多重搜索/替换。

标签: haskell lazy-evaluation memoization


【解决方案1】:

Haskell98 报告 statesarray 在边界参数和关联列表的索引中是严格的,但在值中是非严格的”listArray 类似。

这意味着数组的结构是立即创建的——即n “单元格” values - 但 values 本身是惰性的,这在 Haskell 中很常见。

简化后的函数定义是

import Data.Array
import Data.List
import Data.Ord (comparing)

syrs n = 
    a
    where 
    a = listArray (1,n) $ 0 : map syr [2..n]
    syr x = 
        if y <= n then 1 + a ! y else 1 + syr y
        where 
        y = if even x then x `div` 2 else 3 * x + 1

有了它,

a ! i === (0 : map syr [2..n]) !! (i-1) , i = 1..n
      === if i==1 then 0
                  else (map syr [2..n]) !! (i-2) , i = 2..n
      === if i==1 then 0
                  else syr i

a ! 10的值需要时,按照上面的定义计算,然后存储在数组a中的索引10下。计算它将以通常的方式进行,即。 a ! 5 将被要求,触发 its 计算,并有条件地将结果存储在数组中。

所以,在伪代码中,

syr x = a ! x     , if already calculated and stored in the array
      = 1 + syr y , storing the result in the array under x, if x <= n
      = 1 + syr y , otherwise
  where
  y = ....

Haskell 的常规、递归、惰性求值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-15
    • 2022-11-29
    • 1970-01-01
    • 1970-01-01
    • 2016-04-30
    • 2011-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多