あなたはここに複数の選択肢があります。
- ビッグ配列
- 配列
Bigarraysがそれらの値として数字のみを持つことができますが、彼らはのものとすることができるマッピングします任意のサイズと寸法。また、多次元データにアクセスするための素晴らしいインターフェースも備えています。配列は任意の型の値を持つことができ、配列の配列を作成して多次元空間をモデル化することができます。配列とbigarrayはどちらも必須のデータ構造なので、あなたのコードになります。そのため、永続的なマップを使用してコードを純粋に機能させることをお勧めします(OCamlで練習したい場合は、機能的な部分空間で練習する方がよい)。だから、地図
と
例は、の状態のための型を定義し、座標ましょう:
type state = Dead | Live
type coord = {x : int; y : int}
我々はマップを使用しますので、我々は未実装の状態を必要としません。非人口状態はマップされていません。
今、私たちはボードのデータ構造の実装を定義することができます。
module Board = Map.Make(struct
type t = coord
let compare = compare
end)
使い方の例として、それぞれの人口隣接セルへのユーザ提供関数を適用しますfold_neighbors
と呼ばれる高階関数を定義してみましょう。この一般的なイテレータ機能を使用して
は
let neighbors {x;y} = [
x, y+1;
x+1,y+1;
x+1,y;
x+1,y-1;
x, y-1;
x-1,y-1;
x-1,y;
x-1,y+1;
] |> List.map (fun (x,y) -> {x;y})
let fold_neighbors board cell ~f ~init =
neighbors cell |>
List.fold_left (fun acc n ->
try f acc (Board.find n board)
with Not_found -> acc)
init
、我々はcount_live_neighbors
のような特殊な機能を定義することができます。
let count_live_neighbors =
fold_neighbors ~init:0 ~f:(fun count nb -> match nb with
| Live -> count + 1
| Dead -> count)
実装が無限ボードを前提とし、あなたはそれが有界作りたい場合は、あなたがfold_neighbors
を適応させる必要がありますボードの外にいる人を除外する機能。
アレイの例
もう1つの方法は、通常のアレイを使用する方法です。我々は、300行400列のゼロで満たされたマトリックスを作成する
make_matrix 300 400 0
例えば、所定の大きさの2次元配列を作成した値でそれを充填する便利make_matrix
関数を使用することができます。
この例では、マトリックスに数値を入力するのではなく、状態を入力したいと考えています。3つの状態を表すことができる状態の型が必要ですが、前の例のstate
型を再利用しますが、それをoption
型にラップして、死んだり生きているセルも表現しますSome Dead
またはSome Live
、および未実装1がちょうどNone
となりますので、我々は我々が最初にそれを作成した後、ランダムに基づいてセルを選択するために命を与えることができ、当社のボードを初期化するには
Array.make_matrix width height None
と空のボードを作成することができますように必要な人口密度。 0と1との間の浮動小数点数で密度を表現する。例えば、密度は0.1
であり、約10%のセルが生存することを意味する。より機能的になるために、Array.map
を使用して配列を変換します。インプレース変更と明示的なループや反復がより速く、より慣用もちろんのこと、ちょうど実験のための、より機能的なアプローチを使用してみましょうになります。
let create_board width height density =
Array.make_matrix width height None |>
Array.map (Array.map (fun cell ->
if Random.float 1.0 > density then Some Live else None))
我々は作成されません場合は、我々は、よりきれいにこれを行うことができます最初の手の空のボードですが、初期化されたボードから始まります。このために、我々は、セル毎に異なる値を与えることができますArray.init
機能を使用することができ、ここではより良いcreate_board
機能の例です。
let create_board width height density =
Array.init height (fun _ ->
Array.init width (fun _ ->
if Random.float 1.0 > density then Some Live else None))
Array.init
関数は、要素のインデックスを持つユーザーに提供関数を呼び出します。私たちの場合、生命の可能性は座標に依存しないので、ポジションを無視することができます。そのため、_
を使用して、引数を使用しません。
回答をいただきありがとうございます。私はその行列を使うことにしました。与えられた集団密度に基づいて生きている細胞と死んだ細胞のいずれかをマトリックスに埋め込む方法があるかどうか分かりますか?私はmake_matrixの幅の高さ密度を使用しています –
さて、私は配列の例で答えを更新しました。ハッピーキャリング:) – ivg