【问题标题】:Haskell List Comprehension - Right Angled TrianglesHaskell List Comprehension - 直角三角形
【发布时间】:2021-06-21 19:11:03
【问题描述】:

我目前正在从Learn You a Haskell for Great Good! 书中学习 Haskell。其中一个示例涉及创建表示三角形的 3 项元组:

let triangles = [ (a,b,c) | c <- [1..10], b <- [1..10], a <- [1..10] ]

然后我们对原始列表推导应用一些条件,只创建直角三角形:

let rightTriangles = [ (a,b,c) | c <- [1..10], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2]

生产结果:

ghci> rightTriangles
[(3,4,5),(6,8,10)]

我会通过以下方式产生这个结果:

let rightTriangles = [(a,b,c) | c <- [1..10], b <- [1..10], a <- [1..10], a^2 + b^2 == c^2, a < b && b < c]

谁能准确解释本教程的直角代码是如何工作的?这两种方法都应用了过滤器来确保a < b && b < c,但我无法准确地描述 c <- [1..10], b <- [1..c], a <- [1..b] 发生了什么。

如果有人能解释正在发生的事情,我将非常感激,如果可能的话,也许可以提供某种说明。我是函数式编程的新手,非常想了解它是如何工作的。

谢谢!

【问题讨论】:

  • 另一种思考方式是将abc 想象为(x, y, z) 坐标。使用[1..10] + 过滤,您可以制作一个完整的 10×10×10 立方体,搜索所需的点,然后切掉两个三角形块,留下 x c <- [1..10], b <- [1..c], a <- [1..b] 效率更高一些,因为它从直接构造体积 x ≤ y ≤ z 开始,跳过了无论如何都会被切掉的大部分点。这是一个隐式/固有/通过构造(尽管没有强制执行)的属性示例。

标签: haskell functional-programming list-comprehension


【解决方案1】:

简答:因为b &lt;- [ 1 .. c ] 意味着b 总是小于或等于c

c &lt;- [1..10]b &lt;- [1..c]a &lt;- [1..b] 是生成器。在 Python 中,这看起来像一个 for 循环,所以类似于;

data = []
for c in range(1, 11):
    for b in range(1, c+1):
        for a in range(1, b+1):
            if a*a + b*b == c*c:
                data.append((a, b, c))

您可以将此视为一种循环机制,其中变量cba 被赋值。

因为它被实现为b &lt;- [1 .. c],这意味着b小于或等于c,因为这是范围的最大界限。

由于该技巧也适用于a &lt;- [ 1 .. b],这意味着对于我们考虑的所有 3 元组,a ≤ b ≤ c。由于a ≥ 1,如果满足约束a2+b2b≤c /sup>=c2,表示ab,因为如果b 例如为一,表示a2 + 1 = b2,同样适用于a时间>。所以我们知道 a 和 b 。

a 也不能等于b。如果是这样,这意味着 2×a2 = c2,这意味着 c = √2 ×a。既然abc都是整数值,那a = b是不可能的,因为那c不可能是整数,因为整数乘以无理数是无理数号码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-29
    • 1970-01-01
    • 1970-01-01
    • 2020-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多