【问题标题】:Equation solving with Haskell用 Haskell 求解方程
【发布时间】:2025-12-23 23:55:15
【问题描述】:

我想在 Haskell 中找到直到 N 的所有数字,满足方程(费马定理):

一些解决方案可能是:

所以我尝试在 Haskell 中这样做:

main :: IO ()
main =  do
    let arr = [ z * z == x * x + y * y | x <- [1..13], y <- [1..13], z <- [1..13]] in print arr

我得到布尔值列表:

[False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,...]

该列表中总共有 4 个 True 值。我的问题是:

  1. 如何获得满足给定方程的所有元组 (x, y, z)?
  2. 如何计算该数组中的 True 值?

更新: 还有一个问题。我如何计算有多少数字不属于任何元组?我认为它在逻辑上会这样:

solutions2 = [
    (z)
  | x <- [1..13]
  , y <- [x..13]
  , z <- [y..13]
  , z * z /= x * x + y * y, 
  z * z /= x * x - y * y, 
  z * z /= y * y - x * x
  ]

但是返回的数字太多了。关于如何找到不属于任何三元组的数字的任何想法?

更新2: 我一直在尝试和挖掘更多。如何将我从输入中读取的数字 n 传递给先前定义的函数(计算方法)?我希望能够获得解决方案数组,打印它及其长度。

sol n = solution = [
    (x, y, z)
  | x <- [1..n]
  , y <- [x..n]
  , z <- [y..n]
  , z * z == x * x + y * y
  ]

main :: IO ()
main = do 
    putStrLn "Enter n:"
    n <- getLine
    let mySol = sol n
    print (mySol)

但我给了我错误:

error: parse error on input `='

还有:

Failed, no modules loaded.

【问题讨论】:

  • 只是几点说明: 1. 您的示例似乎排除了重复项 (3,4,5) / (4,3,5) - 您可以通过 x &lt;- [1..13], y &lt;- [x..13] 来做到这一点(您会得到一个也可以订购)# 2. 同样,z 必须至少与y(和x)一样大,因此您也可以更改为z &lt;- [y..13] - 这是一个轻微的性能改进,对于 13 来说并不重要但它将为 1300 万;)
  • 能否请您看一下第二次更新? @Carsten
  • 问题出在sol n = solution = [ 行,只需将其更改为sol n = [ - 请注意,您不应该用更多问题更新一个问题 - 这不是 * 的工作方式 - 您应该提出新问题而是
  • 还请注意,let mySol = sol n(很可能)在getLine 读入String 时会出现另一个错误,但您需要Int - 试试@987654323 @ 而不是 getLine

标签: haskell math functional-programming list-comprehension equation


【解决方案1】:

您可以使用过滤器并生成 (x, y, z) 元组以防过滤器满足:

solutions = [
    (x, y, z)
  | x <- [1..13]
  , y <- [1..13]
  , z <- [1..13]
  , z * z == x * x + y * y
  ]

main :: IO ()
main =  do
    print solutions

这给了我们六个解决方案:

Prelude> solutions 
[(3,4,5),(4,3,5),(5,12,13),(6,8,10),(8,6,10),(12,5,13)]

您也可以打印print (length solutions)获取解数。

【讨论】:

  • 谢谢,它有帮助。但是我可以以某种方式过滤掉重复的解决方案吗?我的意思是,而不是 (3,4,5) AND (4,3,5) 我只会得到其中一个?
  • 看我对你的问题的评论 - 这可以通过改变迭代来轻松完成
  • @vytaute:你可以让y只枚举[1 .. x],这样效率更高,也意味着y &lt;= x,从而对结果进行重复数据删除。
  • 非常感谢!你能这么好心,也看看问题更新,我还有一个问题:)
  • @vytaute:可以用vals = [xi | (x, y, z) &lt;- solutions, xi &lt;- [x, y, z]]获取元组中的值列表,然后用length (filter (`notElem` vals) [1 .. 13])计算元素个数