这是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 = 3
,x' = 10
,10 < n
,它将继续then
子句:a ! 10
。但目前尚未计算a ! 10
。那么程序如何进行呢?
答案 0 :(得分:2)
Haskell98报告states,“float scaleWidth = ((float) destWidth) / width;
float scaleHeight = ((float) destHeight) / height;
float scale = Math.max(scaleWidth, scaleHeight);
Matrix matrix = new Matrix();
matrix.postScale(scale, scale);
Bitmap roundBitmap = Bitmap.createBitmap(destWidth + 20, destHeight + 20, Bitmap.Config.ARGB_8888) // This creates a square bitmap of 220*220
BitmapShader shader = new BitmapShader(bitmap, TileMode.CLAMP, TileMode.CLAMP); // The original size of bitmap is 200*200
shader.setLocalMatrix(matrix);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(shader);
Canvas canvas = new Canvas(roundBitmap);
canvas.drawCircle((destWidth + 20) / 2, (destHeight + 20) / 2, destWidth / 2, paint)
在bounds参数和关联列表的索引中是严格的,但在值”中是非严格的。 array
类似。
这意味着数组的结构是立即创建的 - 即用于保存数组的 n “cells”值 - 但值本身是懒惰的,就像在Haskell中一样。
你的函数的定义是简化的
listArray
有了它,
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
中的索引10
下。计算它将以通常的方式进行,即。将要求a
,触发其计算,并有条件地将结果存储在数组中。
所以,在伪代码中,
a ! 5
对Haskell的通常的,递归的,懒惰的评估。