gpt4 book ai didi

haskell : force evaluation/avoid garbage collecting when composing functions

转载 作者:行者123 更新时间:2023-12-01 11:27:18 26 4
gpt4 key购买 nike

我一直在寻找一种优雅的方式来编写这段代码:

import Data.List
import Data.Maybe

combi = [(x,y) | x <- [2..100], y <- [x..100]]

gsp = group (sort [x*y | (x,y) <- combi])
counts = zip (map head gsp) (map length gsp)

multipleProducts x = (fromJust (lookup x counts)) > 1
possibleComb1 = [(x,y) | (x,y) <- combi, multipleProducts (x*y)]

因为我多次重复使用相同的模式,但基于与 [x*y | (x,y) <- combi] 不同的输入集, 我想出了这段代码。

import Data.List
import Data.Maybe

combi = [(x,y) | x <- [2..100], y <- [x..100]]

onlyOneEl e x = (fromJust (lookup x counts)) == 1
where gs = group (sort e)
counts = zip (map head gs) (map length gs)

multipleProducts = not.(onlyOneEl [x*y | (x,y) <- combi])
possibleComb1 = [(x,y) | (x,y) <- combi, multipleProducts (x*y)]

但是,Haskell 似乎计算了 gscount每次我调用 multipleProducts,都会花费大量时间,而不是只计算一次,因为 e 的值对于 multipleProducts 总是相同的。

避免重新计算的最优雅的方法是什么?有什么比预先计算更好的吗 counts使用一个函数并将其存储在局部变量中,然后将其传递给 onlyOneEl没有哪里?

因为我稍后要重用 onlyOneEl基于不同的集合,我想避免有多个 counts变量。

我明白了here为什么它没有对每个函数进行一次评估,但是,我没有使用 x 作为我的最后一个参数,因此不能完全按照这种方式进行。

提前致谢!

最佳答案

您可以以更多的目标为导向重写它。无需学习数学,只需生成数据和过滤,您就可以用更少的计算量实现同样的效果。

生成乘积时,将乘数也添加到元组中,即

combi n = [((x,y),x*y) | x<-[2..n], y<-[x..n]]

现在您可以根据产品进行排序和分组

multi = filter ((>1) . length) . groupBy ((==) `on` snd) . sortBy (comparing snd) . combi

并提取元组的第一个元素,它将是 (x,y) 对以多次给出相同的产品。

map (map fst) (multi 100)

如果你不关心分组,你可以将结果展平,即

concatMap (map fst) (multi 100)

关于 haskell : force evaluation/avoid garbage collecting when composing functions,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36293798/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com