文档结构  
翻译进度:已翻译     翻译赏金:0 元 (?)    ¥ 我要打赏

今天给大家一个Erlang Thursday红包。

过去的这个周末我读了文章  Bro, Do You Even FizzBuzz?!? ,它阐述如何在Clojure里不用取模运算符来解决 FizzBuzz 问题。

在以同样的算法用Ruby来解决这个问题并发布博客后,我想我应该将这个问题用Erlang也来解决,同时也看看有何不同。

-module(fizzbuzz).

-export([fizzbuzz/1]).

fizzbuzz(N) ->
    Results = do_fizzbuzz(N),
    lists:foreach(fun(X) -> io:format("~p~n", [X]) end, Results).

do_fizzbuzz(N) ->
    Fizzes = cycle(["", "", "fizz"], N),
    Buzzes = cycle(["", "", "", "", "buzz"], N),
    FizzBuzzes = lists:zipwith(fun lists:append/2, Fizzes, Buzzes),
    Numbers = lists:seq(1, N),
    lists:zipwith(fun translate/2, Numbers, FizzBuzzes).

cycle(List, N) ->
    lists:sublist(lists:append(lists:duplicate(N, List)), N).

translate(Number, "") ->
    integer_to_list(Number);
translate(_, Translation) ->
    Translation.
第 1 段(可获 0.74 积分)

在Erlang的解决方案里有几个点要注意。

首先,Erlang没有任何懒列表或序列的直接概念,也没有 cycle 函数,所以我只能临时凑合着调用 lists:duplicate, lists:append 和 lists:sublist 来处理一个列表,从而循环处理原列表来生成一个有N个元素的列表。虽然这个做法不是最高效的方式,但是它是可行的。

其次,lists:zipwith 的能力对于一些管道的想法有帮助,因为我们可以处理这些链在一起的元素,而不是必须在不同的步骤中去处理它们。

第 2 段(可获 1.29 积分)

第三,我们不用case语句,而是用一个有guard分支的函数来决定一个翻译存在与否,如果是是否用这个翻译,如果不是是否用这个数字。

我希望这起到抛砖引玉的作用,也希望听到你怎样更高效的方案,或者除了用一般的有guard分支来检查剩余元素的模式匹配的其他方法来解决FizzBuzz问题。

第 3 段(可获 0.99 积分)

文章评论