8
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Erlangでfizzbuzz

Last updated at Posted at 2017-09-11

Erlang勉強中です。逐次プログラミングを一通り勉強したのでfizzbuzzやってみました。
これが正攻法かどうかは謎ですが、一例として自分と同じ初学者の参考になればと思います。

-module(fizzbuzz).
-export([run/2, run/3]).

%% list:fizzbuzzしたリストを返却、out:fizzbuzzした結果を都度出力
%% 1~Nまでの数値リストをfizzbuzz
run(list, N) when is_integer(N) ->
    NumList = make_list(N),
    fizzbuzz(NumList);
run(out, N) when is_integer(N) ->
    NumList = make_list(N),
    fizzbuzz2(NumList);
run(_, _) -> io:format("e.g. : run(out, ~p)~n", [10]).

%% Start~Endまでの数値リストをfizzbuzz
run(list, Start, End) when is_integer(Start), is_integer(End) ->
    NumList = make_list(Start, End),
    fizzbuzz(NumList);
run(out, Start, End) when is_integer(Start), is_integer(End) ->
    NumList = make_list(Start, End),
    fizzbuzz2(NumList);
run(_, _, _) -> io:format("e.g. : run_fizzbuzz(out, ~p, ~p)~n", [5, 10]).

% 引数が2つの場合1~nまで、3つの場合n~mまでの数値リストを作成する
% 初期値sが与えられている場合はs~nまでのリストを作成する。
make_list(MaxNum) -> make_list(1, MaxNum, []).
make_list(MinNum,MaxNum) -> make_list(MinNum, MaxNum, []).
make_list(I, Max, List) when I =< Max-> make_list(I + 1, Max, [I|List]);
make_list(I, Max, List) when I > Max -> lists:reverse(List).

%% 受け取ったリストをfizzbuzz変換したリストを返す
fizzbuzz(NumList) -> fizzbuzz(NumList, []).
fizzbuzz([H|T], Result) -> 
    case {H rem 3, H rem 5} of
        {0,0} -> fizzbuzz(T, [fizzbuzz|Result]);
        {0,_} -> fizzbuzz(T, [fizz|Result]);
        {_,0} -> fizzbuzz(T, [buzz|Result]);
        {_,_} -> fizzbuzz(T, [H|Result])
    end; 
fizzbuzz([], Result) -> lists:reverse(Result).

%% 受け取った数値リストを順にfizzbuzz出力する
fizzbuzz2([H|T]) ->
    case {H rem 3, H rem 5} of
        {0,0} -> io:format("~p:fizz buzz~n", [H]);
        {0,_} -> io:format("~p:fizz~n", [H]);
        {_,0} -> io:format("~p:buzz~n", [H]);
        {_,_} -> io:format("~p~n", [H])
    end, fizzbuzz2(T);
fizzbuzz2([]) -> io:format("End~n").

実行結果

1> c(fizzbuzz).
{ok,fizzbuzz}
2>
2> fizzbuzz:run(list,10).
[1,2,fizz,4,buzz,fizz,7,8,fizz,buzz]
3>
3> fizzbuzz:run(out,10).
1
2
3:fizz
4
5:buzz
6:fizz
7
8
9:fizz
10:buzz
End
ok
4>
4>
4> fizzbuzz:run(list,10, 20).
[buzz,11,fizz,13,14,fizzbuzz,16,17,fizz,19,buzz]
5>
5> fizzbuzz:run(out,10, 20).
10:buzz
11
12:fizz
13
14
15:fizz buzz
16
17
18:fizz
19
20:buzz
End
ok
6>

書いた後に気づいたんですが、「Learn You Some Erlang for Great Good!」によると、
caseを下のように使用するのは読んでいる人を驚かせるらしいです。

case {A,B} of
    Pattern Guards -> ...
end.

 
追記:
コメントでlists:seq/2を教えていただいたので修正してみました。

修正版fizzbuzz

-module(fizzbuzz_kai).
-export([run/2, run/3]).

%% list:fizzbuzzしたリストを返却、out:fizzbuzzした結果を都度出力
%% 1~Nまでの数値リストをfizzbuzz
run(list, N) when is_integer(N), N > 0 -> fizzbuzz(lists:seq(1, N));
run(out, N) when is_integer(N), N > 0-> fizzbuzz2(lists:seq(1, N));
run(_, _) -> io:format("e.g. : run(out, ~p)~n", [10]).

%% From~Toまでの数値リストをfizzbuzz
run(list, From, To) when is_integer(From), is_integer(To), From =< To ->
    fizzbuzz(lists:seq(From, To));
run(out, From, To) when is_integer(From), is_integer(To), From =< To ->
    fizzbuzz2(lists:seq(From, To));
run(_, _, _) -> io:format("e.g. : run_fizzbuzz(out, ~p, ~p)~n", [5, 10]).

%% 受け取ったリストをfizzbuzz変換したリストを返す
fizzbuzz(NumList) -> fizzbuzz(NumList, []).
fizzbuzz([H|T], Result) ->
    case {H rem 3, H rem 5} of
        {0,0} -> fizzbuzz(T, [fizzbuzz|Result]);
        {0,_} -> fizzbuzz(T, [fizz|Result]);
        {_,0} -> fizzbuzz(T, [buzz|Result]);
        {_,_} -> fizzbuzz(T, [H|Result])
    end;
fizzbuzz([], Result) -> lists:reverse(Result).

%% 受け取った数値リストを順にfizzbuzz出力する
fizzbuzz2([H|T]) ->
    case {H rem 3, H rem 5} of
        {0,0} -> io:format("~p:fizz buzz~n", [H]);
        {0,_} -> io:format("~p:fizz~n", [H]);
        {_,0} -> io:format("~p:buzz~n", [H]);
        {_,_} -> io:format("~p:~n", [H])
    end, fizzbuzz2(T);
fizzbuzz2([]) -> io:format("End~n").

実行結果

1> c(fizzbuzz_kai).
{ok,fizzbuzz_kai}
2>
2> fizzbuzz_kai:run(list, 10).
[1,2,fizz,4,buzz,fizz,7,8,fizz,buzz]
3> fizzbuzz_kai:run(out, 10).
1:
2:
3:fizz
4:
5:buzz
6:fizz
7:
8:
9:fizz
10:buzz
End
ok
4>
4> fizzbuzz_kai:run(list, 10, 20).
[buzz,11,fizz,13,14,fizzbuzz,16,17,fizz,19,buzz]
5>
5> fizzbuzz_kai:run(out, 10, 20).
10:buzz
11:
12:fizz
13:
14:
15:fizz buzz
16:
17:
18:fizz
19:
20:buzz
End
ok
6>

8
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?