Erlang入門
Erlang本を入手したので学んでみる。
インストール
debianだとパッケージが用意されている。
# apt-get install erlang erlang-man
erlang-manは以下のようにモジュールを調べられるようになる。
$ erl -man lists
基本
_や大文字で始まるのが変数。_は/dev/nullみたいな変数。
小文字で始まるのがアトム。(アトムとはシンボル定数のようなもの)
=はマッチングして代入する演算子。(ちなみに変数への再代入はできない)
- タプル
- 用途や型の異なるオブジェクトをひとまとまりにする。{}で定義。
- リスト
- 要素内の型を同一なものにそろえる。[]で定義。
例:
1> Point = {point, 20, 30}. 2> {point,X,Y} = Point. 3> X. 20 4> Y. 30
リスト
カンマで区切る
[1,2,3,4]
こうも定義できる。
[1,2 | [3,4] ]
の左側がヘッド(先頭の要素)。右側がテール(ヘッド以外のリスト)。 |
リスト内包表記
リストを作成する式
[構築子||ジェネレータ or フィルター, ...]
- 構築子
- 要素を作る式
- ジェネレータ
- Pattern <- リスト。リストの中でPatternに一致するものが渡される。
- フィルター
- ブール式。ブール式がtrueの場合に渡される。
例:
1> Buy = [{[100,200,250],fruit},{[100],fish}]. 2> [{lists:sum(A),B} || {A,B} <- Buy, B =:= fruit]. [{550,fruit}]
モジュール
.erlに書く。コンパイルすると.beamになる。
とりあえずサンプルで能力が均等になるようにチーム分けするプログラムを書いてみた。
(AoEとかのチームネット対戦ゲーで使うやつ)
以下でコンパイルして実行する。
1> c(team) 2> team:divide([3,4,5,2,6,6]). [{0,[{1,3},{2,4},{5,6}],[{3,5},{4,2},{6,6}]}, {0,[{3,5},{4,2},{5,6}],[{1,3},{2,4},{6,6}]}, {2,[{1,3},{2,4},{3,5}],[{4,2},{5,6},{6,6}]}, {2,[{1,3},{2,4},{3,5},{4,2}],[{5,6},{6,6}]}, {2,[{1,3},{3,5},{5,6}],[{2,4},{4,2},{6,6}]}]
とりあえず候補を5つまで表示するようにしている。
入力のリストは各プレイヤーの能力を数値化したもの。
結果の1行目はPlayer1 Player2 Player5 vs Player3 Player4 Player6
で、チームの能力差0という意味である。
もっと短く書けるのかもしれないが、、、
再帰は慣れんなー、と思ってググってみるとこんなページを見つける。
Schemerはこう考える。
K&Rを読もう(8) 1.7 図解Schemerの再帰脳 - ボクノス
* 「一個前はなんだっけ」
* 「終わりはなんだっけ」
なるほど。
Erlangの大きな特徴の1つとして、分散アプリケーションを簡単に書けるというのがあるが、その辺りはまた後日。。。
team.erl
-module(team). -export(divide/1). pickup(_,0) -> []; pickup(L,1) -> [H|_]=L, [H]; pickup(L,N) -> [H|T]=L, pickup([H],N rem 2) ++ pickup(T,N div 2). pow(_,0) -> 1; pow(N,M) -> N * pow(N,M-1). pickuplist(_,0) -> [[]]; pickuplist(L,N) -> [pickup(L,N)] ++ pickuplist(L,N-1). dividelist(L) -> [{A,L--A}||A <- pickuplist(L,pow(2,length(L)-1)-1)]. sum_level([]) -> 0; sum_level(L) -> [{_,X}|T]=L,X+sum_level(T). divide_leveled_list(L) -> [{abs(sum_level(A)-sum_level(B)),A,B}|| {A,B}<-dividelist(L)]. sort_leveled_list(L) -> lists:sort(fun({X,_,_},{Y,_,_}) -> X<Y end, divide_leveled_list(L)). numbering([],_) -> []; numbering(L,N) -> [H|T]=L,[{N,H}]++numbering(T,N+1). divide(L) -> lists:sublist(sort_leveled_list( numbering(L,1) ),5).
参考文献
- 作者: Joe Armstrong,榊原一矢
- 出版社/メーカー: オーム社
- 発売日: 2008/02/23
- メディア: 単行本(ソフトカバー)
- 購入: 8人 クリック: 284回
- この商品を含むブログ (97件) を見る