Erlang中的Collat​​z序列

Posted

技术标签:

【中文标题】Erlang中的Collat​​z序列【英文标题】:Collatz sequence in Erlang 【发布时间】:2021-05-19 16:05:35 【问题描述】:

我要解决的问题如下: 编写一个名为 collat​​z 的 Erlang 函数,它接受一个参数 N。您可以假设 N 是整数 1 或更大。该函数应打印以 N 开头的 Collat​​z 序列(每行一个数字)。例如,collat​​z( 4 ) 应打印 4、2、1(在单独的行上)。 collat​​z( 6 ) 应该打印 6, 3, 10, 5, 16, 8, 4, 2, 1(在单独的行上)。

我编写的 collat​​z 函数工作正常,但在单独的行上打印输出时遇到困难。下面代码的注释部分是我尝试在单独的行上生成输出。

    collatz(1) -> [1];
    collatz(N) when N rem 2 == 0 ->
    [N|collatz(N div 2)];
    %[io:format("Collatz is : ~p~n",[N])N|collatz(N div 2)];
    collatz(N) ->
    [N|collatz(3*N+1)].
    %[io:format("Collatz is : ~p~n",[N])N|colla[N|collatz(N div 2)]tz(3*N+1)].
    

当我调用 collat​​z(5) 时得到的输出是 [5,16,8,4,2,1]。我希望将这些数字打印在不同的行上。

【问题讨论】:

【参考方案1】:

与其运行整个程序并打印结果,不如考虑在每次迭代之前打印每个元素,例如

collatz(N) -> io:format("~p~n", [N]), collatz(next_collatz(N)).

【讨论】:

【参考方案2】:

您只需要评估io:format/2 之前在您的列表中添加N...

collatz(1) ->
    io:format("Collatz is : 1~n"),
    [1];
collatz(N) when N rem 2 == 0 ->
    io:format("Collatz is : ~p~n", [N]),
    [N | collatz(N div 2)];
collatz(N) ->
    io:format("Collatz is : ~p~n", [N]),
    [N | collatz(3 * N + 1)].

【讨论】:

【参考方案3】:
1> C = fun C(1,_) -> io:format("1~n") ;
2> % rem is not allowed in a guard, it is why I added it in the parameters                            
2> C(N,0)  -> io:format("~p~n",[N]), NN = N div 2,  C(NN, NN rem 2);
3> C(N,_) -> io:format("~p~n",[N]), NN = 3 * N + 1, C(NN, NN rem 2) end.
#Fun<erl_eval.19.97283095>
4> Collatz = fun(N) -> C(N, N rem 2) end.                               
#Fun<erl_eval.44.97283095>
5> Collatz(5).                                                          
5
16
8
4
2
1
ok
6>

【讨论】:

请注意:在警卫中使用 rem 是完全有效的。

以上是关于Erlang中的Collat​​z序列的主要内容,如果未能解决你的问题,请参考以下文章

python 最长的Collat​​z序列(Euler#14)

最大化 Collat​​z 猜想程序 Python 的效率

Collat​​z Conjecture Python - 超过 2 万亿的错误输出(仅限!)

c_cpp 使用libgmp进行Collat​​z。

Collat​​z C++ 代码的问题

序列化 Collat​​or 实例