一个简单的Erlang程序

前几天同事为应聘自动化测试的同学出了 projecteuler 上面的一道题
一个直角三角形三个边 a b c 之和为 1000
且 a b c 皆为整数
求三边之积

有兴趣的读者可以停下来试着写程序跑上一跑

用Python来写这个程序可以是这个样子:

def triangle(N):
    for a in range(1, N/4):
        for b in range(1, N/2):
            c = N - a - b
            if a * a + b * b == c * c:
                return a * b * c

if __name__ == "__main__":
    print triangle(1000)

(由题目可推得两条直角边a b不可能大于或等于 N/2 且 小边小于 N/4)

下面看看用 Erlang 语言如何解决这个问题
按照惯例,先说下Erlang的一个语法:List Comprehensions
据说要译为 列表推导,请看代码

$ erl
1> L = [1, 3, 5].
2> lists:map(fun(X) -> X*X end, L).
[1,9,25]
3> [X*X || X <- L].
[1,9,25]

句3即为列表推导

注:句2为一个方便的函数定义,类似Python语言中的 lambda 函数
Out 一下,给个例子

1> Z = fun(X) -> X * 2 end.
2> Z(3).
6

下面回到正题,现在来看看如何用Erlang来计算直角边之积吧:

-module(tri).
-export([triangle/1]).

triangle(N) ->
    [{A * B * (N - A - B)} ||
        A <- lists:seq(1, N div 4),
        B <- lists:seq(1, N div 2),
        A*A + B*B == (N - A - B) *(N - A - B)].

测试:

$ erlc tri.erl
$ erl
1> tri:triangle(1000).
[{31875000}]

:这个算法是比较直接的,多数人都可以想到
开始我觉得大概这样已经是最优解了
但我另一个同事在那里用数字公式算来算去
仅仅用一层循环就搞定了。。。
我后来在 stackoverflow 上看到也有人提到这个算法