第一个问题,Common LISP 和 Haskell 的新手,请友善。
我在 Common LISP 中有一个函数 - 下面的代码 - 旨在判断三角形的面积是否是整数(整数?)。
(defun area-int-p (a b c)
(let* ((s (/ (+ a b c) 2))
(area (sqrt (* s (- s a) (- s b) (- s c)))))
(if (equal (ceiling area) (floor area))
t
nil)))
这应该使用海伦公式 https://en.wikipedia.org/wiki/Triangle#Using_Heron.27s_formula给定三边的大小,计算三角形的面积,并通过比较天花板和地板来确定它是否为整数。我们被告知,等边三角形的面积永远不是整数。因此,为了测试该函数是否正常工作,我使用参数运行了它333
。这是我得到的回报:
CL-USER> (area-int-p 333 333 333)
NIL
完美的!有用。为了进一步测试它,我用参数运行它3333
。这就是我得到的回报:
CL-USER> (area-int-p 3333 3333 3333)
T
出了什么问题,这不应该发生!
因此,我尝试使用以下希望等效的 Haskell 函数来看看会发生什么:
areaIntP :: (Integral a) => a -> a -> a -> Bool
areaIntP a b c =
let aa = fromIntegral a
bb = fromIntegral b
cc = fromIntegral c
perimeter = aa + bb + cc
s = perimeter/2
area = sqrt(s * (s - aa) * (s - bb) * (s - cc))
in if ceiling area == floor area
then True
else False
这就是我得到的:
*Main> areaIntP 3333 3333 3333
False
*Main> areaIntP 333 333 333
False
看起来很完美。受此启发,我在 Haskell 中使用以下函数来计算等腰三角形的周长总和,其中第三边与其他边仅相差一个单位,是一个积分面积,且周长低于 1,000,000,000。
toplamArtilar :: Integral a => a -> a -> a -> a
toplamArtilar altSinir ustSinir toplam =
if ustSinir == altSinir
then toplam
else if areaIntP ustSinir ustSinir (ustSinir + 1) == True
then toplamArtilar altSinir (ustSinir - 1) (toplam + (3 * ustSinir + 1))
else toplamArtilar altSinir (ustSinir - 1) toplam
toplamEksiler :: Integral a => a -> a -> a -> a
toplamEksiler altSinir ustSinir toplam =
if ustSinir == altSinir
then toplam
else if areaIntP ustSinir ustSinir (ustSinir - 1) == True
then toplamEksiler altSinir (ustSinir - 1) (toplam + (3 * ustSinir - 1))
else toplamEksiler altSinir (ustSinir - 1) toplam
sonuc altSinir ustSinir =
toplamEksiler altSinir ustSinir (toplamArtilar altSinir ustSinir 0)
(ustSinir
表示上限,altSinir
顺便说一下下限。)
跑步sonuc
与论据2
and 333333333
然而,我的堆栈溢出了。在 Common LISP 堆栈中运行等效函数是可以的,但是area-int-p
函数不可靠,可能是因为解释器推断的数字类型的边界。
毕竟,我的问题有两个:
1) 如何解决 Common LISP 函数中的问题area-int-p
?
2) 如何在 Emacs 中或从终端运行 GHCi 时防止上述 Haskell 函数的堆栈溢出?
对于那些弄清楚我想在这里实现什么目标的人请注意:请不要告诉我使用 JavaBigDecimal
and BigInteger
.
在非常好的回复后进行编辑:我一并提出了两个问题,并从非常乐于助人的人那里收到了非常令人满意的、新手友好的答案和关于风格的注释。谢谢。